通过在移动赋值运算符中使用std::swap来重用析构函数逻辑有意义吗
Does it make sense to reuse destructor logic by using std::swap in a move assignment operator?
考虑以下内容:
class Example : boost::noncopyable
{
HANDLE hExample;
public:
Example()
{
hExample = InitializeHandle();
}
~Example()
{
if (hExample == INVALID_HANDLE_VALUE)
{
return;
}
FreeHandle(hExample);
}
Example(Example && other)
: hExample(other.hExample)
{
other.hExample = INVALID_HANDLE_VALUE;
}
Example& operator=(Example &&other)
{
std::swap(hExample, other.hExample); //?
return *this;
}
};
我的想法是,析构函数很快就会在"其他"上运行,因此我不必通过使用swap在move赋值运算符中再次实现析构函数逻辑。但我不确定这是一个合理的假设。这样可以吗?
想象一下:
// global variables
Example foo;
struct bar {
void f() {
x = std::move(foo); // the old x will now live forever
}
Example x;
}
类似的习惯用法,复制和交换(或者在本例中,移动和交换),可以确保析构函数立即运行,我认为这是一个更好的语义。
Example& operator=(Example other) // other will be moved here
{
std::swap(hExample, other.hExample);
return *this;
} // and destroyed here, after swapping
应该可以,但它几乎不比推荐的按值传递技术好,在这种情况下,移动构造函数将用于这种情况。
我的想法是,析构函数将很快在"其他"上运行
那么你的想法是有缺陷的。你可以从任何你有非常量访问权限的对象中移动。在此之后,该对象可以无限期地继续存在。
从技术上讲,将当前数据放在旧对象中是正确的。但这不是一个好主意。最好使用堆栈变量:
Example& operator=(Example &&other)
{
Example temp(std::move(other)); //other is now empty.
std::swap(hExample, temp); //our stuff is in `temp`, and will be destroyed
return *thisl
}
或者更好的是(如果你没有使用Visual Studio)将你的东西存储在一个正确支持移动的包装器中,并让编译器生成的移动构造函数为你完成这项工作。
相关文章:
- 基类中的默认析构函数禁用子类中的移动构造函数(如果有成员)
- C++中的基元类型有析构函数吗?
- 有没有办法保证析构函数的相对顺序?
- 在调用其析构函数之前,是否有任何实际理由检查某些东西是否可破坏?
- 有一个构造函数,但有两个析构函数
- 拥有"受保护的非虚拟析构函数"与"受保护虚拟析构构函数"有什么好处
- 如果在C++中不需要构造函数或析构函数,是否有必要显式声明它?
- "virtual"对C++析构函数有何影响?
- 错误:在“(”标记之前进行预期的构造函数、析构函数或类型转换.即使我有一个构造函数
- 为什么这个 Deque 析构函数有内存泄漏
- 抛出可由C++98和C++1x编译的析构函数.有更好的方法吗
- 我不明白析构函数有什么问题?
- 从 STL 容器继承并删除"新"运算符以防止由于缺少虚拟析构函数而导致未定义的行为是否有意义?
- C++03 12.4/12对通过指针显式调用基类析构函数有何说明
- "= default"析构函数和空析构函数有什么区别?
- 删除析构函数的意义何在
- 通过在移动赋值运算符中使用std::swap来重用析构函数逻辑有意义吗
- 用另一个虚拟析构函数覆盖"empty"虚拟析构函数有什么害处吗?
- c++的析构函数有问题
- 没有虚方法的虚析构函数有什么害处吗?