繁体   English   中英

共享指针指向的 object 的生命周期

[英]Lifetime of object pointed to by shared pointer

举个例子

struct A {
   int x = 0;
};

struct B {
   std::shared_ptr<A> mA;
   
   void setA(std::shared_ptr<A> a) {
     mA = a;
   }
};

struct C {

  B initB() {
    A a;
    
    A *aPtr = &a;
    B b;
    b.setA(std::make_shared<A>(aPtr));
    return b;
 } 
};

现在在main()方法中

C c;
B b = c.initB();

initB()中的局部变量a退出 scope 一个 function 完成执行。 但是有一个指向它的共享指针。 当a离开scope时,共享指针指向的object会被删除吗? 最后*(b.mA)会给出A的有效实例吗?

首先,这不会编译。

    B initB() {
        A a;

        A* aPtr = &a;
        B b;
        b.setA(std::make_shared<A>(/*aPtr*/a););
        return b;
    }

您必须传递正在共享的实际 object,而不是指向它的指针。 现在,为了找出这个问题的答案,我们可以为每个 function 编写通知程序,并添加构造函数和析构函数,这样我们就可以看到发生了什么。

#include <memory>

#include <iostream>

struct A {
    int x = 0;
    A() {
        std::cout << "A's CTOR" << std::endl;
    }
    ~A() {
        std::cout << "A's DTOR" << std::endl;
    }
};

struct B {

    B() {
        std::cout << "B's CTOR" << std::endl;
    }

    ~B() {
        std::cout << "B's DTOR" << std::endl;
    }

    std::shared_ptr<A> mA;

    void setA(std::shared_ptr<A> a) {
        std::cout << "Entering setA()" << std::endl;
        mA = a;
        std::cout << "Exiting setA()" << std::endl;
    }
};

struct C {

    C() {
        std::cout << "C's CTOR" << std::endl;
    }

    ~C() {
        std::cout << "C's DTOR" << std::endl;
    }

    B initB() {
        std::cout << "Entering initB()" << std::endl;
        A a;

        A* aPtr = &a;
        B b;
        b.setA(std::make_shared<A>(/*aPtr*/a));
        std::cout << "Exiting initB()" << std::endl;
        return b;
    }
};

int main() {
    std::cout << "Entering Main" << std::endl;
    C c;
    B b = c.initB();
    std::cout << "Exiting Main" << std::endl;
    return 0;
}

output:

Entering Main
C's CTOR
Entering initB()
A's CTOR
B's CTOR
Entering setA()
Exiting setA()
Exiting initB()
B's DTOR
A's DTOR
Exiting Main
B's DTOR
A's DTOR
C's DTOR

有趣的是,你有没有发现发生了什么? 有 2 个A's DTOR std::make_share<A>(a)实际上制作了a的副本,然后将shared_ptr制作为a 由于我们没有定义复制赋值运算符/构造函数,编译器会自动生成一个,这就是为什么我们只有一个A's CTOR 所以即使我无法想象你会在一个地方这样做,它也会有一个有效的 A 实例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM