簡體   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