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

C++ 是否可能有一个静态对象和一个指向同一对象的静态std::shared_ptr?,c++,shared-ptr,C++,Shared Ptr,鉴于以下类别: class Foo : public Base { public: static const Foo FOO; static const std::shared_ptr<Foo> FOO_PTR; // .. virtual methods, etc }; 基本上,我们首先创建静态FOO对象,然后用指向该对象的指针初始化shared_ptr。当然这个对象不是通过new创建的,所以如果shared\u ptr试图删除它,世界很可能会结束。为了避免这种情况,

鉴于以下类别:

class Foo : public Base {
public:
  static const Foo FOO;
  static const std::shared_ptr<Foo> FOO_PTR;
  // .. virtual methods, etc
};
基本上,我们首先创建静态
FOO
对象,然后用指向该对象的指针初始化
shared_ptr
。当然这个对象不是通过
new
创建的,所以如果
shared\u ptr
试图删除它,世界很可能会结束。为了避免这种情况,我们要做的最后一件事是从第一个创建另一个
shared_ptr
,增加它的引用计数,并泄漏它,这样原始
shared_ptr
将永远不会尝试删除它的指针

当然,这让我感到恶心,我正在寻找更好的解决方案


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

不确定它是否有助于您解决API限制,但您可以改变这种情况,动态创建一个共享的\u ptr-object,让
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);
}
class-Foo{
公众:
静态常数Foo&Foo;
静态常量std::shared_ptr FOOPTR;
};
const std::shared_ptr Foo::FOOPTR=make_shared();
常量Foo&Foo::Foo=*Foo::FOOPTR;
int main(){
常量Foo*f1=Foo::FOOPTR.get();
常量Foo*f2=&Foo::Foo;
printf(“%p==%p\n”,(void*)f1,(void*)f2);
}

为什么希望共享指针指向未动态分配的对象?您不会使用
shared\u ptr
,因为整个指针都在管理堆内存,而这里没有。您需要
静态常量Foo*Foo\u PTR
@juanchopanza-因为API中嵌入了使用
shared_ptr
来保存Foo类型的对象(特别是像Foo这样共享公共基类和
virtual
函数的许多其他类型)。这些对象中的大多数实际上是动态创建和销毁的,
shared_ptr
的使用是传统的,但是也有一些单例对象,比如
FOO
FOO_PTR
,它们只创建了一次,但必须与现有的
shared_PTR
API很好地结合起来。@zzxyz-当然这就是我在这个简单示例中想要的,但是我的手被束缚在实际用例中,这显然并不简单。
shared\u ptr
的使用非常广泛,并嵌入到API中,如果不付出巨大的努力,并且不破坏与无数现有客户机的二进制兼容性,就无法对其进行更改。这不是设计问题:我承认设计很糟糕。如何最大限度地减少损害是一个务实的问题。你可以通过一个习惯,什么都不做。。。或者对虚拟共享ptr使用“别名”构造函数……谢谢,这实际上让我走了一半:它与源代码兼容,但仍然会破坏与现有客户端的二进制兼容性(因为引用在ABI级别是不同的类型)。不过这是很好的半步。有了一些链接器的魔力,就有可能实现一个渐进的过渡。
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);
}