Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

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;
}
like image 995
Sideshow Bob Avatar asked May 02 '13 14:05

Sideshow Bob


People also ask

Does move assignment call destructor?

Default move assignment calls destructor, copy assignment doesn't.

Is the destructor automatically called in C++?

A destructor is a member function that is invoked automatically when the object goes out of scope or is explicitly destroyed by a call to delete .

What is the default assignment operator?

If a class definition does not declare a parameterless constructor, a copy constructor, a copy assignment operator, or a destructor, the compiler will implicitly declare them. These are called default operators.

Is there a default assignment operator in C++?

In C++, the compiler automatically generates the default constructor, copy constructor, copy-assignment operator, and destructor for a type if it does not declare its own.


2 Answers

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.

like image 156
Sebastian Redl Avatar answered Sep 22 '22 13:09

Sebastian Redl


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.

like image 45
Grizzly Avatar answered Sep 23 '22 13:09

Grizzly