You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 15:02:09