One reason to do this would be to force all instances of the object to be owned by shared_ptr's (instead of statically constructed). This is especially helpful when using shared_from_this().
For example, consider the following program:
#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());
}
};
In this program, a Foo object can access/pass a shared pointer to itself, similar to how it can access/pass the this pointer. When classMemberFunc() is called on an object of Foo, globalFunc receives a reference to a shared_ptr the holds Foo.
However, with this design, Foo needs to be owned by a shared_ptr in the first place.
int main()
{
// valid use
auto sptr = std::make_shared<Foo>();
sptr->classMemberFunc();
}
If a Foo object isn't owned by a shared_ptr, shared_from_this() has undefined behavior before C++17 and a runtime error in C++17.
int main()
{
// invalid use - undefined behavior or runtime error
Foo nonPtrFoo;
nonPtrFoo.classMemberFunc();
}
We would like to prevent this at compile time. We can do this using the static "create" method and a private constructor.
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();
}