C++ 我可以在移动赋值操作符中调用析构函数吗?

C++ 我可以在移动赋值操作符中调用析构函数吗?,c++,c++11,dry,move-assignment-operator,C++,C++11,Dry,Move Assignment Operator,呼叫d-tor内部移动分配操作员是否是良好做法 下面是一些示例代码: VectorList &operator = (VectorList &&other){ ~VectorList(); // if this is not a good practice, // I will need to paste whole d-tor here. _buffer = std::move(other._buffer

呼叫d-tor内部移动分配操作员是否是良好做法

下面是一些示例代码:

VectorList &operator = (VectorList &&other){
    ~VectorList(); // if this is not a good practice,
                   // I will need to paste whole d-tor here.

    _buffer     = std::move(other._buffer       );
    _dataCount  = std::move(other._dataCount    );
    _dataSize   = std::move(other._dataSize     );

    other._clear();

    return *this;
}

我应该使用此代码,还是应该将swap()用于移动构造对象?

Scott Meyers说不要使用
swap()


关于您当前的实现,您似乎可以做得更简单。我认为析构函数实际上删除了
\u buffer
,其他功能几乎没有。如果这是真的,那么您应该用
delete\u buffer

~VectorList
代替更难推理的显式析构函数调用,它实际上会破坏对象

之后,存储空间就不用了。您可以使用构造函数在那里构造一个新对象,但是简单地访问成员要么是未定义的行为,要么需要语言律师找到允许定义它的漏洞


即使已定义,它也是危险的,因为在销毁自动存储对象时引发异常是坏消息。另外,如果赋值给类实际上是派生类型,那么dtor调用本身就是UB

这两种方法都不值得。好处太小了


更好的选择是拷贝交换(这至少很容易得到正确的结果:它可以防止一些优化),或者从dtor和赋值中重构出“清除”代码。然后在两个点调用它。

您是否考虑过创建一个函数来“清理”对象,并从析构函数和移动赋值操作符调用此函数?这与析构函数通常不负责将对象返回到初始化状态非常相似,因此我不太愿意这样做。为什么不调用
this->clear()
?@Nick作为旁注,我希望您知道
std::move
不会“移动”任何东西,它只是对右值引用的转换。如果
\u buffer
是原始指针,则
\u buffer=other.\u buffer足够了。是的,我是,但斯科特·梅耶斯“告诉”我你应该用move来做,因为更好的风格和表现意图。std::move是一个简单的强制转换…@nick swap Implementation严格地说比上面的好,但是。@nick Scott Meyers的观点是相当沉默的:时间并没有在三指针赋值中丢失,而是在
delete
调用中丢失。如果在缓存中,
new
/
delete
对在250个周期的范围内,则分配大约需要五个周期。而且,
temp=a;a=b;b=温度;删除b
删除一个;a=b;b=零PTR:两个版本都将
a
b
加载到寄存器中,然后将值存储到
a
b
。Scott Meyers在撰写本文时显然被
a=b
的抽象蒙蔽了双眼。“当自动存储对象被销毁时抛出异常是个坏消息”——谁在这么做?从析构函数中抛出几乎从来都不是一个好主意,除非除了崩溃之外别无选择。如果有人这样做,你可能也会遇到破坏问题,所以我不认为防御是一个重要的考虑因素。@voidstar不是“在破坏期间”,而是“在被破坏时”——在(希望后面的)ctor完成之前的任何时候。在对象的重构过程中,如果抛出异常,则最终将得到一个未构造的对象。如果在自动存储中,它将被双重销毁。我明白你的意思,但是答案文本中的语法是模糊的,听起来你害怕抛出析构函数。然而,你的意思是,真正的风险是赋值运算符代码中的抛出操作。顺便说一句,由于其他原因,在分配操作员代码期间不考虑异常的影响是不安全的。。。不匹配的字段状态也可能同样糟糕,比如缓冲区长度错误。手动调用析构函数除了运行该函数的代码外,什么都不做。delete操作符不会以某种方式被使用,对象也不会因为过早超出范围而被释放。销毁用placement new构造的对象时,通常会看到显式析构函数调用。@克里斯:不,你错了。我没有提到删除或解除分配,所以这部分是正确的,但不相关,因为它与我没有说的内容不一致。调用析构函数不仅仅是运行析构函数体:它会销毁对象,结束其生命周期。存储仍然存在,但不再包含已销毁类型的对象。指向该存储的指针的有效使用现在受到了极大的限制,直到新对象的生命周期在该存储中开始。与dtor具有相同主体的函数不会这样做。