[英]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.