Reputation: 14408
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.
Temple Constructor
Invoking pointer access operator
-- Welcome Temple
Invoking De-referencing Operator
-- Welcome Temple
Temple Destructor
Destructor is Invoked
#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
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
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
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