繁体   English   中英

为什么默认赋值运算符不首先调用析构函数?

[英]Why doesn't default assignment operator call the destructor first?

因此,在下面的示例中,我们使类Foo*this = Foo()替换自身。 我很高兴我只是测试了这个,因为事实证明,在这种情况下,旧Foo的析构函数不会被调用。 我想这是因为默认赋值运算符只使用memcpy ...但是作为一个语言设计问题...为什么不让默认赋值运算符首先破坏已分配的对象以防止意外?

http://codepad.org/9WCo6yZ5

#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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM