[英]Why doesn't default assignment operator call the destructor first?
因此,在下面的示例中,我们使类Foo
用*this = Foo()
替换自身。 我很高兴我只是测试了这个,因为事实证明,在这种情况下,旧Foo
的析构函数不会被调用。 我想这是因为默认赋值运算符只使用memcpy
...但是作为一个语言设计问题...为什么不让默认赋值运算符首先破坏已分配的对象以防止意外?
#include <iostream>
using namespace std;
class MustBeDestroyed //(for some reason not shown here)
{
public:
int i;
MustBeDestroyed(int i) : i(i) {}
~MustBeDestroyed() { cout << "destroyed contained class " << i << endl; }
};
class Foo
{
public:
MustBeDestroyed x;
Foo(int y) : x(y) {}
void replace_myself(int y) { Foo f(y); *this=f; }
void print() { cout << "This is outer/inner class " << x.i << endl; }
~Foo() { cout << "destroyed outer class " << x.i << endl; }
};
int main()
{
Foo a(1);
a.print();
a.replace_myself(2);
a.print();
return 0;
}
因为首先破坏对象会终止生命。 然后,您必须调用构造函数来启动新对象的生命周期。 但是operator =的行为不是要销毁当前对象并创建另一个对象,而是要为现有对象分配一个新值。
基本上,你违反了3的规则。
为什么赋值会调用析构函数? 它完全按照它的说法执行:它调用赋值运算符。 编译器生成的赋值运算符只是显而易见:将旧obejct中的所有成员分配给new(使用它们的赋值操作)。 没有更多,没有更少。 这正是着名的三人统治的原因。
现在它为什么不调用析构函数:这将结束对象的生命周期。 虽然理论上可能构造一个新对象而不是旧对象,但是在异常面前这种方法通常是不正确的( 关于这个问题,请查看这个问题 ),因此它不能用于一般情况。 如果它采用你提出的方法,它不会为成员调用赋值运算符,而是调用析构函数/复制构造函数。 这意味着不会遵守自定义分配行为(实际上不需要与复制行为相同)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.