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