Option 1 crashes the app on shared_from_this() with bad_weak_ptr, while option 2 works fine, why? the only difference i see is where the clone is being created - in the Clone() function or in line with creating shared_ptr for the clone, in both cases the shared_from_this requirement of already having shared_ptr with ownership of this when using shared_from_this() is met
class Base
{
public:
virtual Base* Clone() = 0;
};
class Derived : public Base, public std::enable_shared_from_this<Derived>
{
public:
Base* Clone() override
{
return new Derived(*this);
}
void test()
{
std::shared_ptr<Derived> ptr = shared_from_this();
}
};
int main()
{
std::shared_ptr<Base> obj = std::make_shared<Derived>();
//std::shared_ptr<Base> clone = std::shared_ptr<Base>(obj->Clone()); // option 1
std::shared_ptr<Base> clone = std::shared_ptr<Base>(new Derived(*std::static_pointer_cast<Derived>(obj))); // option 2
std::shared_ptr<Derived> derived = std::static_pointer_cast<Derived>(clone);
derived->test();
return 0;
}
CodePudding user response:
You can't new an object that derives from enable_shared_from_this and for it to safely work since the new object doesn't actually have a shared_ptr container.
Instead of this:
Base* Clone() override
{
return new Derived(*this);
}
This:
shared_ptr<Base> Clone() override
{
return make_shared<Derived>(*this);
}
Similar adjustment in the base class declaration:
virtual shared_ptr<Base> Clone() = 0;
