Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does my destructor appear to be called more often than the constructor?

#include<iostream>
using namespace std;

class A{
public:
    static int cnt;
    A()
    { 
        ++cnt; 
        cout<<"constructor:"<<cnt<<endl;
    }
    ~A()
    {
        --cnt;
        cout<<"destructor:"<<cnt<<endl;
    }
};

int A::cnt = 0;

A f(A x){
    return x;
}
int main(){
    A a0;
    A a1 = f(a0);
    return 0;
}

The program will output:

constructor:1
destructor:0
destructor:-1
destructor:-2

The constructor and destructor don't appear in pairs?

like image 988
user1694746 Avatar asked Sep 24 '12 14:09

user1694746


People also ask

Why is my destructor being called twice?

C++ destructors are called twice for local objects when exiting a function via a nested return statement.

How do you stop a destructor from being called?

The best way to not call a particular destructor is to not create an instance of that object to begin with. Failing that, take the code you don't want to run out of the destructor. I can't conceive any reason why doing this would be legitimate.

Can destructor be called without constructor?

Yes, the destructor is nothing more than a function. You can call it at any time. However, calling it without a matching constructor is a bad idea.

Can a destructor be called multiple times?

According to the linked question, this is because the destructor is called multiple times for the pointer member, a consequence of the copy constructor being called multiple times when copying, causing an attempted deallocation of memory already deallocated.


2 Answers

You need to add a copy constructor that increases the counter.

A(const A&)
{ 
    ++cnt; 
    cout<<"copy constructor:"<<cnt<<endl;
}

If you don't add it explicitly, the compiler generates one that does nothing with the counter cnt.

This expression

A a1 = f(a0);

is creating copies of a0, which make use of the copy constructor. The exact number of copies may vary depending on copy elision, but your cnt should be 0 at the end of the program.

Note: In C++11, you should also consider the possibility of a compiler generated move copy constructor, however, once you declare your own copy constructor, the compiler no longer generates the move version.

like image 140
juanchopanza Avatar answered Oct 11 '22 18:10

juanchopanza


You are not tracking all constructors, only the default constructor. The compiler has generated a copy constructor and used it a couple of times, accounting for the 2 objects that are listed as destroyed and not as created.

like image 39
David Rodríguez - dribeas Avatar answered Oct 11 '22 19:10

David Rodríguez - dribeas