Whoami
Whoami

Reputation: 14408

Smart pointer implementation: when is the destructor invoked for pointee?

I have the below code, and wrapped the Temple object with a smart pointer. I understood the concept, but what I did not understand is when the held object's destructor is invoked.

Even thought, i have not implemented ~mySmartPointer, the template destructor is invoked.

OUTPUT

Temple Constructor

Invoking pointer access operator

-- Welcome Temple

Invoking De-referencing Operator

-- Welcome Temple

Temple Destructor

Destructor is Invoked

Code

#include <iostream>
using namespace std;

template <typename T>
class mySmartPointer 
{
private:
    T *_object;    
public: 
    explicit mySmartPointer(T * newObject) {
       _object = newObject;
    };
    ~mySmartPointer() { cout <<"Destructor is Invoked "<<endl;}; 

    T operator *() {
        cout  <<" Invoking De-referencing Operator "<<endl;
        return * _object;
    };

    T * operator ->() {
        cout <<"Invoking pointer access operator "<<endl;
        return _object;
    };
};

class Temple
{
private:
    int x,y;
public:
    void printWelcome() {
        cout <<"-- Welcome Temple "<<endl;
    }
    Temple() {
        cout <<"Temple Constructor"<<endl;
    }
    ~Temple() {
        cout <<"Temple Destructor "<<endl;
    }
};

int main(int argc, char ** argv) {
    mySmartPointer<Temple> t (new Temple);
    t->printWelcome();      
    (*t).printWelcome();
}

Upvotes: 0

Views: 737

Answers (3)

Drew Dormann
Drew Dormann

Reputation: 63704

This is the code that's causing the confusion.

  T operator *() 
  {
      cout  <<" Invoking De-referencing Operator "<<endl;
      return * _object;
  };

When you call this code, a copy of Temple is created. This copy is getting destroyed automatically.

Change it to this:

  T& operator *() 
  {
      cout  <<" Invoking De-referencing Operator "<<endl;
      return * _object;
  };

Upvotes: 1

Sarfaraz Nawaz
Sarfaraz Nawaz

Reputation: 361272

It is because you're returning a copy of the object from operator*().

Look at the return type here:

T operator *() 
{
     cout  <<" Invoking De-referencing Operator "<<endl;
     return * _object;
};

You need to return T& instead.

It is better if you define T const & operator*() const also, for const smart pointer object!

Upvotes: 0

Luchian Grigore
Luchian Grigore

Reputation: 258548

This

T operator *() 

returns by value - and it's that copy that's being destroyed.

If you change it to

T& operator *() 

you'll see it there'll be no destructor of the object invoked. Note that this should have two versions:

T const& operator *() const;
T& operator *() 

and similar for operator->. This is so that you can call const methods on const objects.

If you're doing this for educational purposes, great, otherwise use one of the existing implementations.

Upvotes: 7

Related Questions