为了说明我的问题,我举了一个例子:
#include <iostream>
using namespace std;
struct A
{
void doSomething (){
cout << "Something\n";
}
};
struct B
{
A a;
A *getA ()
{
return &a;
}
};
int
main ()
{
B *b = new B ();
A *a = b->getA ();
// POINT 1
if (nullptr != a)
{
a->doSomething ();
}
delete b;
b = nullptr;
// POINT 2
if (nullptr != a)
{
a->doSomething ();
}
return 0;
}
这在我的机器上编译和运行没有错误,但是如果你检查代码,在标记为“POINT 2”的注释后面的行上确实存在悬空指针问题。
由于 b
被删除,因此 a
现在无效(因为它被 b
的 dtor 删除)。
所以我可以使用一个共享指针来解决这个问题,但是即使在 b
被删除之后,这也会保留 a
的实例,而且我也无法在堆栈上分配 a
。这是我想避免的两件事。相反,我只是想知道 a
是否仍然有效。
我也可以使用一个唯一的指针,但是我只能有一个 a
实例,这也不是我想要的,我想要指向 a< 的指针的许多拷贝
.
那么是否有一些现有的指针/引用类型允许我这样做?这是好主意还是坏主意?
最佳答案
您刚刚发现了所有权语义的奇妙之处:)
如何解决这个问题取决于您的应用程序的设计:您需要什么以及您试图实现什么。
在这种情况下,如果您真的想共享对象的所有权,请使用 std::shared_ptr
它保持剩余指针的引用计数,以便最后删除对象;可能 std::weak_ptr
如果您只需要检查对象是否仍然存在,但又不想让它存活的时间超过需要的时间。
但是,请注意(ab)使用共享指针可能是糟糕设计的标志。
顺便说一句,你的 A a;
成员没有分配到堆栈中(即标题是错误的)。
关于c++ - 当返回可能在 C++ 堆栈上分配的成员时,最好的指针/引用类型是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54467270/