Given the following class:
class Foo : public Base {
public:
static const Foo FOO;
static const std::shared_ptr<Foo> FOO_PTR;
// .. virtual methods, etc
};
Is it possible to make it so that FOO_PTR
points to FOO
?
It seems hard since the usual way of creating a shared pointer is by taking ownership of a dynamically created pointer (e.g., via new Foo{}
) or via std::make_shared<Foo>()
both of which create a new object and don't really allow you to point the shared_ptr
to FOO
. Similarly, if I create the pointer first, it will have a different identity from FOO
and so I think I am screwed here too.
A really dirty hack could be something like:
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
Basically we create the static FOO
object first, then initialize the shared_ptr<FOO>
with a pointer to that object. Now of course this object wasn't create via new
so if the shared_ptr
ever tries to delete it the world will probably end. To get around that the last thing we do is create another shared_ptr
from the first, incrementing its reference count, and leak it, so the original shared_ptr
will never try to delete its pointer.
Naturally, this makes me feel gross and I'm looking for a better solution.
Now an obvious solution would not be expose the FOO
and/or FOO_PTR
static objects in the first place but my hands are tied here and I cannot change that part of the design.
Not sure if it helps you with the API restrictions, but you could turn it around in that you create a shared_ptr-object dynamically and let foo
be of type Foo&
then:
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);
}