0

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();
}
Useless
  • 64,155
  • 6
  • 88
  • 132
Whoami
  • 13,930
  • 19
  • 84
  • 140
  • Once you've fixed that problem, have a look at the [Rule of Three](http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three). Your pointer will go horribly wrong if it's copied. – Mike Seymour Jan 24 '13 at 16:48

3 Answers3

7

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.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
1

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;
  };
Drew Dormann
  • 59,987
  • 13
  • 123
  • 180
0

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!

Nawaz
  • 353,942
  • 115
  • 666
  • 851