Одна из причин сделать это - заставить все экземпляры объекта принадлежать 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. Когда classMemberFun c () вызывается для объекта Foo, globalFun c получает ссылку на shared_ptr, удерживаемую Foo.
Однако в этом дизайне 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();
}
Мы хотели бы предотвратить это во время компиляции. Мы можем сделать это с помощью метода stati c "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();
}