C++ shared_ptr指向对象时析构函数多次调用问题求助
关于TMat析构函数多次调用的原因解释
测试代码
#include <iostream> #include <memory> using namespace std; 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); } 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; { cout << "> creating cmat" << endl; TMat mymat; cout << "> creating view" << endl; TView v; v.print(); v.setMat(mymat); v.print(); } cout << "*** End App" << endl; return 0; }
运行结果
*** 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. setMat方法执行后,为何TMat的析构函数被调用?
setMat的参数是TMat mat,属于值传递。调用v.setMat(mymat)时,会先创建一个mymat的临时副本作为函数参数。当setMat函数执行完毕,这个临时参数mat的生命周期结束,会被销毁,触发一次TMat的析构函数——这就是本次析构调用的原因。
2. 离开对象作用域时,为何TMat的析构函数被调用两次?
离开作用域时,有两个TMat对象会被销毁:
- 第一个是栈上的
mymat:它是作用域内直接创建的局部对象,作用域结束时会被销毁,触发一次析构。 - 第二个是
shared_ptr<TMat>持有的堆上TMat对象:当TView对象v被销毁时,其成员mat_ptr的引用计数变为0,shared_ptr会自动释放它管理的堆上TMat对象,触发第二次析构。
加上setMat里临时参数的那次析构,总共三次析构调用,与运行结果的输出完全对应。
内容的提问来源于stack exchange,提问作者Vincent31
相关产品推荐
相关产品推荐

