矢量分配和异常安全
Vector assignment and exception safety
我读过关于异常安全的文章,并提出了以下问题:
在A类中,m_value和m_data应相互一致。但是如果
m_data = data;
throw类不变量将被破坏。
class A
{
public:
void Set(const std::vector<unsigned int>& data)
{
m_value = ComputeValue(data);
m_data = data;
}
private:
int m_value; //That should be consistent with vector
std::vector<unsigned int> m_data;
}
我应该用一些复制和交换的变体来保护这个代码吗?在这样的每一行代码中使用复制和交换是一个好的决定吗?或者这个代码可以按原样使用?
这是我的解决方案,但我不确定,我应该使用它,还是它是多余的复杂性:
void Set(const std::vector<unsigned int>& data)
{
std::vector<unsigned int> tmp_data(data);
m_value = ComputeValue(tmp_data);
m_data.swap(tmp_data);
}
附加:
另一个问题:我应该写我自己的异常安全分配运算符或交换函数,使其可以像这样使用吗:
class B
{
public:
SetA(const A& a)
{
A tmp_a(a);
m_a.swap(tmp_a);
}
private:
A m_a;
}
在A级中
void A::swap(A& rhs)
{
using std::swap;
swap(m_data, rhs.m_data);
swap(m_value, rhs.m_value);
}
如果ComputeValue可以抛出,那么使用复制和交换习惯用法是为函数提供强大异常安全保障的最简单方法。然而,与其通过const引用传递并在函数中进行复制,不如通过值传递向量,因为如果函数传递了r值,编译器就可以调用move构造函数。
void Set(std::vector<unsigned int> data)
{
m_value = ComputeValue(data);
m_data.swap(data);
}
如果ComputeValue不能抛出,那么所有这些麻烦都是不必要的,您可以在计算新值之前将向量(通过const引用传递)分配给成员变量。
关于你的第二个问题,我认为只将函数参数分配给成员变量没有任何好处,前提是A的复制分配运算符提供了强大的异常安全保证(它应该这样做),使用复制和交换习惯用法也很容易实现。
相关文章:
- C++代码中的异常安全
- 编写"anti-lack of memory"异常安全代码
- std:string::substr 异常安全吗?
- 如何以异常安全的方式使用放置新?
- 异常安全服务器
- 实现 std::vector::p ush_back 强异常安全
- 标准::unique_ptr和异常安全
- 如何使用QThreads使无锁生产者-消费者线程交换更加异常安全
- 使功能异常安全
- 与构造函数参数相关的异常安全的习语
- uninitialized_copy() 异常安全吗?
- 为什么我们需要 RAII 来解决异常安全问题
- 异常安全构造函数
- 关于 swap() 操作的异常安全 - 这有什么问题?
- std::vector::擦除异常安全
- 异常安全 - 用于可靠回滚对象状态的模式
- 异常安全的 for 循环
- 异常安全代码和移动语义
- 向量::插入的异常安全保证是什么?
- 异常安全和make_unique