代码之家  ›  专栏  ›  技术社区  ›  Vincent31

对象上的C++共享指针多次调用析构函数

  •  1
  • Vincent31  · 技术社区  · 1 年前

    我正在学习C++智能指针。我做了以下测试: 类TView使用指向类TMat的智能指针。

    我已经看到TMat析构函数被调用了不止一次。我不明白为什么。

    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;
    }
    

    结果是:

    *** 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”的活动范围,析构函数被调用。我不明白为什么。
    2. 当我生活在对象的范围内时,我只期望调用TMat析构函数一次。

    为什么析构函数被调用不止一次?

    1 回复  |  直到 1 年前
        1
  •  2
  •   Sam Varshavchik    1 年前

    为什么析构函数被调用不止一次?

    因为你不止一个 Tmat 存在的对象。每个 对角矩阵 当对象的生命周期结束时,该对象将被销毁。

    void setMat(TMat mat){
    

    你有一个 对角矩阵 对象的参数 setMat 类函数。什么时候 setMat 返回所有被销毁的参数。

    mat_ptr = make_shared<TMat>(mat);
    

    此(副本)构造另一个 TMat 对象,由新创建的 shared_ptr .

    但是 mat 仍然是该类函数的参数,并且当它返回时 小地毯 被销毁并调用其析构函数。

    还有第三个 对角矩阵 对象: mymat 在里面 main 。有三个 对角矩阵 对象,这就是为什么您看到析构函数被调用了三次。