我编写的类(通常作为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
答案 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而起作用,但是您可以尝试一下。)
不过,我不得不说,这听起来不像是班级应该负责的事情。这是一种向后编程。
通常,最好(如果可能的话)如果对象包含在shared_ptr中,在堆中,在堆栈中,在堆栈中,在指针中,在向量中或作为对象包含,则它们不是自我感知的数据成员,或作为全局成员。一旦他们意识到如何进行生命周期管理,他们就会变得更加受约束。不必要地如此。
shared_from_this
是(可以说)一种反模式。但是...有时可能是必要的反模式。
我宁愿避免使用enable_shared_from_this
,而是让人们使用他们认为合适的Foo
,例如通过精瘦的unique_ptr
。