Search code examples
c++pointersshared-ptrdestructor

C++ shared pointer on a object call destructor more than one time


I'm studing C++ smart pointer. I have done the following test: A class TView use a smart pointer to a class TMat.

I have seen that the TMat destructor is called more than one time. I don't understand why.

class TMat {
    public:
        int a = 100;

        TMat() {
            cout << " --> TBuffer Constructor called" << endl;
        }
        ~TMat() {
            cout << " --> TBuffer Destructor called" << endl;
        }
};

class TView {
    public:
        shared_ptr<TMat> mat_ptr;

        TView():mat_ptr(nullptr) {
            cout << " --> TView Constructor called" << endl;
        }
        ~TView() {
            cout << " --> TView Destructor called" << endl;
        }
        void setMat(TMat mat){
            cout << "> Setting Mat" << endl;
            mat_ptr = make_shared<TMat>(mat);
        }       **// 1. After this point, the destructor of TMat is called ???**
        void print(){
            if(mat_ptr != NULL ) cout << "a:    " << mat_ptr->a << endl;
            cout << "nb ref:    " << mat_ptr.use_count() << endl;
        }
};

int main() {
    cout << "*** Start App" << endl; // prints Hello Vince
    {
        cout << "> creating cmat" << endl;
        TMat mymat;

        cout << "> creating view" << endl;
        TView v;
        v.print();
        v.setMat(mymat);
        v.print();
    } **// 2. After this point, the destructor of TMat is called 2 times ???**

    cout << "*** End App" << endl;
    return 0;
}

The result is:

*** Start App
creating cmat
--> TBuffer Constructor called
creating view
--> TView Constructor called
nb ref: 0
Setting Mat
--> TBuffer Destructor called
a:  100
nb ref: 1
--> TView Destructor called
--> TBuffer Destructor called
--> TBuffer Destructor called
  1. Living scope of the method "setMat", the destructor is called. I don't understand why.
  2. When I live the scope of the objects I expect the call of TMat destructor only one time.

Why the destructor is called more than one time ?


Solution

  • Why the destructor is called more than one time ?

    Because you have more than one Tmat objects in existence. Each Tmat object gets destroyed, when its lifetime ends.

    void setMat(TMat mat){
    

    You have a Tmat object that's a parameter to this setMat class function. When setMat returns all of its parameters get destroyed.

    mat_ptr = make_shared<TMat>(mat);
    

    This (copy) constructs another TMat object, that's owned by the newly-created shared_ptr.

    But mat is still a parameter to this class function, and when it returns mat gets destroyed and its destructor gets invoked.

    There's also a third Tmat object: the mymat in main. There are three Tmat objects in total, and that's why you see the destructor getting invoked three times.