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
Why the destructor is called more than one time ?
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.