Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Verify at compile time that objects are created as shared_ptr

There are classes that I write (often as part of boost::asio) whose objects depend on being wrapped in a shared_ptr because they use shared_from_this(). Is there a way to prevent an object from being compiled if it's not instantiated in a shared_ptr?

So, what I'm looking for:

std::shared_ptr<MyClass> a = std::make_shared<MyClass>(); // should compile fine
std::unique_ptr<MyClass> a = std::make_unique<MyClass>(); // compile error
MyClass a; // compile error
like image 565
The Quantum Physicist Avatar asked Dec 27 '18 19:12

The Quantum Physicist


1 Answers

Make its constructor private and give it a static factory member function that creates a shared_ptr. Don't forget to document your design decision in a comment!

// Thing that foos the bar
struct Foo : std::enable_shared_from_this<Foo>
{
   // Returns a shared_ptr referring to a new instance of Foo
   static std::shared_ptr<Foo> CreateShared()
   {
      return std::shared_ptr<Foo>(new Foo);
   }

private:
   // To avoid bugs due to the shared_from_this base,
   // we restrict Foo creation to being via CreateShared().
   Foo() = default;
};

(I can't imagine that std::make_shared would work due to the private ctor, but you can try it.)

I've got to say, though, this doesn't sound like the sort of thing a class should be taking responsibility for. It's kind of programming backwards.

To steal Eljay's words:

In general, it is best (if possible) that objects are not self-aware if they are contained in a shared_ptr, or on the heap, or on the stack, or by pointer, or in a vector, or as a data member, or as a global. As soon as they are self-aware of how they are life-cycle managed, they become a lot more constrained. Unnecessarily so. shared_from_this is (arguably) an anti-pattern. But... sometimes it may be a necessary anti-pattern.

I would prefer avoiding enable_shared_from_this and letting people use your Foo however they see fit, such as through a nice lean unique_ptr.

like image 84
Lightness Races in Orbit Avatar answered Sep 21 '22 14:09

Lightness Races in Orbit