在编译时验证是否将对象创建为shared_ptr

时间:2018-12-27 19:34:42

标签: c++ c++11 boost-asio shared-ptr typetraits

我编写的类(通常作为boost::asio的一部分)的对象依赖于包装在shared_ptr中,因为它们使用shared_from_this()。如果没有在shared_ptr中实例化对象,是否有办法防止其被编译?

所以,我要寻找的是

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

1 个答案:

答案 0 :(得分:13)

将其构造函数设为私有,并为它提供创建shared_ptr的静态工厂成员函数。不要忘了在注释中记录您的设计决策!

// 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;
};

(我无法想象std::make_shared会由于私有ctor而起作用,但是您可以尝试一下。)

不过,我不得不说,这听起来不像是班级应该负责的事情。这是一种向后编程。

要窃取Eljaywords

  

通常,最好(如果可能的话)如果对象包含在shared_ptr中,在堆中,在堆栈中,在堆栈中,在指针中,在向量中或作为对象包含,则它们不是自我感知的数据成员,或作为全局成员。一旦他们意识到如何进行生命周期管理,他们就会变得更加受约束。不必要地如此。 shared_from_this是(可以说)一种反模式。但是...有时可能是必要的反模式。

我宁愿避免使用enable_shared_from_this,而是让人们使用他们认为合适的Foo,例如通过精瘦的unique_ptr