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

问题描述 投票:0回答: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 析构函数。

为什么析构函数被调用多次?

c++ pointers shared-ptr destructor basic
1个回答
0
投票

为什么析构函数被调用多次?

因为你存在多个

Tmat
对象。每个
Tmat
对象在其生命周期结束时都会被销毁。

void setMat(TMat mat){

您有一个

Tmat
对象,它是此
setMat
类函数的参数。当
setMat
返回时,它的所有参数都会被销毁。

mat_ptr = make_shared<TMat>(mat);

此(副本)构造另一个

TMat
对象,该对象由新创建的
shared_ptr
拥有。

但是

mat
仍然是此类函数的参数,当它返回时
mat
被销毁并调用其析构函数。

还有第三个

Tmat
对象:
mymat
中的
main
。总共有三个
Tmat
对象,这就是为什么您会看到析构函数被调用三次。

© www.soinside.com 2019 - 2024. All rights reserved.