是否有可能有一个静态对象和一个指向同一对象的静态std :: shared_ptr?

时间:2017-11-28 22:51:51

标签: c++ shared-ptr

鉴于以下课程:

class Foo : public Base {
public:
  static const Foo FOO;
  static const std::shared_ptr<Foo> FOO_PTR;
  // .. virtual methods, etc
};

是否有可能使FOO_PTR指向FOO

似乎很难,因为创建共享指针的常用方法是获取动态创建的指针(例如,通过new Foo{})或通过std::make_shared<Foo>()的所有权,这两者都创建了一个新对象并且#39; t确实允许您将shared_ptr指向FOO。同样,如果我先创建指针,它将与FOO具有不同的身份,所以我想我也被搞砸了。

非常脏的黑客可能是这样的:

Foo Foo::FOO = Foo{};
std::shared_ptr<Foo> Foo::FOO_PTR = &Foo::FOO;  // dirty hack
Foo* dummy = new shared_ptr<Foo>(FOO_PTR);      // leaky, yuck

基本上我们首先创建静态FOO对象,然后用指向该对象的指针初始化shared_ptr<FOO>。当然,这个对象并不是通过new创建的,所以如果shared_ptr试图删除它,世界可能就会结束。为了解决这个问题,我们做的最后一件事是从第一个开始创建另一个shared_ptr,增加它的引用计数,然后泄漏它,因此原始的shared_ptr将永远不会尝试删除它的指针。

当然,这让我感觉很糟糕,我正在寻找更好的解决方案。

现在一个明显的解决方案不会首先公开FOO和/或FOO_PTR个静态对象,但我的手被束缚在这里,我无法改变那个部分设计。

1 个答案:

答案 0 :(得分:1)

不确定它是否可以帮助您解决API限制,但您可以通过动态创建shared_ptr对象并让foo类型为Foo&来解决它:

class Foo {
public:
    static const Foo &FOO;
    static const std::shared_ptr<Foo> FOOPTR;
};

const std::shared_ptr<Foo> Foo::FOOPTR = make_shared<Foo>();
const Foo &Foo::FOO = *Foo::FOOPTR;

int main() {
    const Foo* f1 = Foo::FOOPTR.get();
    const Foo* f2 = &Foo::FOO;

    printf("%p == %p \n",(void*)f1,(void*)f2);
}