The below code snippet is seen at cppreference.
I am curious about what the intention of Best::getptr()
is? When should I use this method in practice? Maybe a simple demo code helps a lot.
struct Best : std::enable_shared_from_this<Best> // note: public inheritance
{
std::shared_ptr<Best> getptr() {
return shared_from_this();
}
// No public constructor, only a factory function,
// so there's no way to have getptr return nullptr.
[[nodiscard]] static std::shared_ptr<Best> create() {
// Not using std::make_shared<Best> because the c'tor is private.
return std::shared_ptr<Best>(new Best());
}
private:
Best() = default;
};
I wrote a simple code snippet to use shared_from_this()
, but I still can't see anything meaningful.
If I want to create a new instance, I just call Foo::Create()
. If I have not called Foo::Create
, Foo::getPtr()
is meaningless (i.e. it could not be invoked at all) since there is no valid instance yet.
If I miss something, please let me know.
#include <iostream>
#include <memory>
class Foo : public std::enable_shared_from_this<Foo> {
private: //the user should not construct an instance through the constructor below.
Foo(int num):num_(num) { std::cout << "Foo::Foo\n"; }
public:
~Foo() { std::cout << "Foo::~Foo\n"; }
int DoSth(){std::cout << "hello world" << std::endl; return 0;}
std::shared_ptr<Foo> getPtr() { return shared_from_this();}
static std::shared_ptr<Foo> Create() {
Foo* foo = new Foo(5);
return std::shared_ptr<Foo>(foo);
}
private:
int num_;
};
int main()
{
auto sp = Foo::Create();
sp->DoSth();
Foo& foo = *sp.get();
auto sp1 = foo.getPtr();
std::cout << sp.use_count() << std::endl;
}
CodePudding user response:
shared_from_this()
is intended to be used from within the shared class itself (hence its name), not so much by an external entity, which can always have access to a shared_ptr
to that class.
For example, you can have a class Database
that hands out View
s, which have to keep a back-pointer to the Database
:
struct View;
struct Database : enable_shared_from_this<Database>
{
auto GetView() { return make_unique<View>(shared_from_this()); }
};
struct View
{
shared_ptr<Database> db;
View(shared_ptr<Database> db) : db(move(db)) {}
};