简体   繁体   中英

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

So in the following example, we cause class Foo to replace itself with *this = Foo() . I'm glad I just tested this because it turns out in this circumstance, the destructor of the old Foo doesn't get called. I guess that's because the default assignment operator just uses memcpy ... but as a language design question ... why wouldn't you make the default assignment operator destroy the assigned-to object first to prevent accidents?

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;
}

Because destroying the object first would end the lifetime. Then you would have to invoke a constructor to start the new object's lifetime. But the behavior of operator= isn't to destroy the current object and create another, but to assign a new value to the existing object.

Basically, you violated the rule of 3.

Why would assignment call the destructor? It does exactly what is says it does: It calls the assignment operator. The compiler generated assignment operator simply does the obvious: assignment of all members from the old obejct to the new (using their assignment operation). Nothing more, nothing less. This is exactly the reason for the famous rule of three .

Now as to why it doesn't call the destructor: That would end the lifetime of the object. While it is theoretically possibly to construct a new object inplace of the old one, that approach is typically incorrect in the face of exception ( look at this question for more about that ), so it can't be used in the general case. Besides if it did the approach you proposed, it wouldn't call the assignment operators for the members, but destructor/copy constructor instead. That means that custom assignment behaviour (which doesn't actually need to be the same as copy behaviour) would not be honored.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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