简体   繁体   English

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

[英]Lifetime of object pointed to by shared pointer

Take the following example举个例子

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

Now in main() method现在在main()方法中

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

Local variable a in initB() goes out of scope one function finishes executing. initB()中的局部变量a退出 scope 一个 function 完成执行。 However there is a shared pointer pointing to it.但是有一个指向它的共享指针。 Will the object the shared pointer points get deleted when a goes out of scope?当a离开scope时,共享指针指向的object会被删除吗? Finally will *(b.mA) give a valid instance of A ?最后*(b.mA)会给出A的有效实例吗?

Firstly, this doesn't compile.首先,这不会编译。

    B initB() {
        A a;

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

You have to pass the actual object being made shared, not a pointer to it.您必须传递正在共享的实际 object,而不是指向它的指针。 Now, to find out the answer to this problem, we can write notifiers for each function, and add constructors and destructors so we can see what is happening.现在,为了找出这个问题的答案,我们可以为每个 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;
}

The output: 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

Interesting, did you catch what happened?有趣的是,你有没有发现发生了什么? There are 2 A's DTOR s.有 2 个A's DTOR std::make_share<A>(a) actually makes a copy of a and then makes a shared_ptr to a . std::make_share<A>(a)实际上制作了a的副本,然后将shared_ptr制作为a Since we didn't define a copy assignment operator/constructor, the compiler automatically makes one, and that is why we only have one A's CTOR .由于我们没有定义复制赋值运算符/构造函数,编译器会自动生成一个,这就是为什么我们只有一个A's CTOR So even though I can't imagine a place where you would do this, it will have a valid instance of A.所以即使我无法想象你会在一个地方这样做,它也会有一个有效的 A 实例。

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

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