Sideshow Bob
Sideshow Bob

Reputation: 4716

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

Upvotes: 17

Views: 8538

Answers (2)

Grizzly
Grizzly

Reputation: 20201

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.

Upvotes: 3

Sebastian Redl
Sebastian Redl

Reputation: 72044

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.

Upvotes: 8

Related Questions