c++ - C++ 隐式生成的赋值运算符的异常安全性

标签 c++ exception assignment-operator exception-safety

我的理解是 C++ 隐式生成 赋值运算符会执行成员方式复制(这似乎也得到了 this answer 的证实)。但是,如果在成员复制期间抛出异常(例如,因为无法分配该成员的资源),被复制的对象是否会陷入无效状态?

也就是说,隐式生成的赋值运算符是否只实现了基本保证,而没有实现强保证?

如果我们想要为我们的类拷贝提供 strong 保证,我们是否必须使用 copy-and-swap 习惯用法手动 实现赋值运算符?

最佳答案

如果你想提供一个异常保证,并且默认的赋值运算符不是 nothrow,那么通常你需要写一个。

默认的复制分配甚至不一定能实现基本的保证,即不泄漏任何资源并且保留类不变量。分配一些数据成员但不是全部可能会使目标处于不满足类不变量的状态,具体取决于特定的类。

所以你必须评估你的类的默认运算符——如果它可以抛出,并且通过抛出使对象处于“无效”状态,那么你必须抑制它。或者削弱定义的类不变量,但这对用户帮助不大。

有(至少)一种特殊情况。如果除了一个之外的所有数据成员都没有赋值,并且特殊的具有强异常安全赋值,并且是类中的 first 数据成员,那么默认赋值运算符也将是强安全的.如果您依赖它,您可能需要非常仔细地评论它,但是,它可能被证明非常脆弱!

关于c++ - C++ 隐式生成的赋值运算符的异常安全性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13341456/

相关文章:

c++ - 复制构造函数还是赋值运算符?我错过了什么?

c++ - 赋值运算符重载 : returning void versus returning reference parameter

c++ - 临时构造函数和复制构造函数

c++ - Numpad 键事件导致 GetKeyboardState 卡住键

c++ - 计算具有随机扩展名的页面上的点击次数

algorithm - 当循环中出现异常时,在继续下一次迭代之前尝试该操作 3(有限)次的最佳方法是什么?

exception - 跳过异常(exception) Doctrine 迁移

C++ - 从 valgrind 中删除无效

c# - Linq : 中的最佳异常处理方法

c++ - 运算符 = 重载