Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Destructor not called when object on stack is overwritten

Tags:

c++

destructor

Today I was wondering about c++ destructors so I wrote a small test program. That answered my original question but raised a new one which is:
The following program:

#include "stdafx.h"
#include <vector>
#include <iostream>
using namespace std;
class test
{
public:
    int id;
    vector<test> collection;
    test(){}
    test(int id_in){id = id_in;}
    ~test(){cout << "dying: " << id << "\n";}
};

int _tmain(int argc, _TCHAR* argv[])
{
    {
        test obj(1);
        obj.collection.push_back(test(2));
        obj.collection.push_back(test(3));
        cout << "before overwrite\n";
        obj = test(4);
        cout << "before scope exit\n";
    }
    int x;
    cin >> x;
}

produces the following output:

dying: 2
dying: 2
dying: 3
before overwrite
dying: 2
dying: 3
dying: 4
before scope exit
dying: 4

Why don't I see a destructor for my test object with id 1? If its destructor isn't called when it is overwritten, than what calls the destructors of the instances in its vector?

like image 919
Hari Avatar asked Aug 17 '12 10:08

Hari


People also ask

What is destructor in C++?

What is a destructor? Destructor is an instance member function which is invoked automatically whenever an object is going to be destroyed. Meaning, a destructor is the last function that is going to be called before an object is destroyed.

How do I explicitly call the destructor for an object?

To explicitly call the destructor for an object, s, of class String, use one of the following statements: The notation for explicit calls to destructors, shown in the preceding, can be used regardless of whether the type defines a destructor. This allows you to make such explicit calls without knowing if a destructor is defined for the type.

When is the destructor of a class called?

The class's destructor is called, and the body of the destructor function is executed. Destructors for nonstatic member objects are called in the reverse order in which they appear in the class declaration.

What is the Order of destruction when an object is deleted?

Order of destruction When an object goes out of scope or is deleted, the sequence of events in its complete destruction is as follows: The class's destructor is called, and the body of the destructor function is executed. Destructors for nonstatic member objects are called in the reverse order in which they appear in the class declaration.


1 Answers

You violate the Rule of Three by creating a destructor, but no assignment operator.

From reading that, you can interpret your code as follows:

When the line

obj = test(4);

is compiled, a temporary instance of test is created with id 4.

Then, the assignment operator is called. Since you did not provide one, the compiler generated one for you that looks like this:

test& operator=(const test& other)
{
    id = other.id;
    collection = other.collection;
    return *this;
}

The id 1 is simply overwritten with the 4 from the temporary, and for the collection assignment, the assignment operator of std::vector is called.

std::vector's assignment operator deletes all previously contained elements, which is why you see

dying: 2
dying: 3

in your output. Finally, the temporarily created obj instance with id 4 is deleted, causing

dying: 4

to appear for the first time. When obj goes out of scope, you see the

dying: 4

output once more.

like image 106
Timbo Avatar answered Sep 26 '22 17:09

Timbo