这样做的一个原因是强制对象的所有实例由 shared_ptr 拥有(而不是静态构造)。这在使用 shared_from_this() 时特别有用。
例如,考虑以下程序:
#include <memory>
class Foo;
void globalFunc(const std::shared_ptr<Foo> &) {
// do something with the ptr
}
class Foo
: public std::enable_shared_from_this<Foo>
{
public:
Foo() {}
void classMemberFunc()
{
globalFunc(shared_from_this());
}
};
在这个程序中,Foo 对象可以访问/传递一个指向自身的共享指针,类似于它访问/传递 this 指针的方式。当对 Foo 的对象调用 classMemberFunc() 时,globalFunc 会收到对持有 Foo 的 shared_ptr 的引用。
但是,在这种设计中,Foo 首先需要由 shared_ptr 拥有。
int main()
{
// valid use
auto sptr = std::make_shared<Foo>();
sptr->classMemberFunc();
}
如果 Foo 对象不属于 shared_ptr,则 shared_from_this() 在 C++17 之前具有未定义的行为,并且在 C++17 中存在运行时错误。
int main()
{
// invalid use - undefined behavior or runtime error
Foo nonPtrFoo;
nonPtrFoo.classMemberFunc();
}
我们希望在编译时防止这种情况发生。我们可以使用静态“create”方法和私有构造函数来做到这一点。
class Foo
: public std::enable_shared_from_this<Foo>
{
public:
static std::shared_ptr<Foo> create() // force shared_ptr use
{
return std::shared_ptr<Foo>(new Foo);
}
void classMemberFunc()
{
globalFunc(shared_from_this());
}
private:
Foo() {} // prevent direct construction
};
int main()
{
// valid use
auto sptr = Foo::create();
sptr->classMemberFunc();
// invalid use - now compile error
Foo nonPtrFoo;
nonPtrFoo.classMemberFunc();
}