我正在调试一些代码,并且遇到了崩溃的代码片段,问题是单例指针和本地指针不是同一地址。我不确定为什么会这样。
代码大致如下:
class B;
class I_A : public std::enable_shared_from_this<I_A> {
public:
virtual std::shared_ptr<B> make() = 0;
};
class A : public I_A {
public:
std::shared_ptr<B> make() override {
return std::make_shared<B>(shared_from_this());
}
};
static std::shared_ptr<I_A> getInstance() {
static std::shared_ptr<I_A> ptr;
if(!ptr) {
std::cout << "Making new instance\n";
ptr = std::make_shared<A>();
}
std::cout << "Ptr is " << ptr << '\n';
return ptr;
}
class B {
public:
B(const std::shared_ptr<I_A>& ptr) : ptr(ptr) {
std::cout << "In B() " << ptr << '\n';
}
void foo() {
std::cout << "B::ptr " << ptr << '\n';
assert(ptr == getInstance());
}
private:
const std::shared_ptr<I_A>& ptr; // Potential problem here
};
int main() {
auto bPtr = getInstance()->make();
bPtr->foo();
}
但是,如果我将shared_ptr<I_A>
的副本存储在B中而不是存储引用,则一切正常。
如果我的理解是正确的,则单例永远不要更改地址,但是B::ptr
和getInstance()
的地址不同。
知道为什么吗?
答案 0 :(得分:6)
对于任何const std::shared_ptr<T>&
,您应该(大约)从不使用T
。只需使用std::shared_ptr<T>
。您会使用T * const &
吗?
您正在观察的问题是,您从std::shared_ptr<I_A>
获得的A::shared_from_this()
的实例是临时的,并且在您可以使用时已经不复存在您的B
。然后,您使用悬挂的参考,其行为不确定。