Как насчет вызова shared_from_this для объектов, выделенных стеком? enable_shared_from_this в списке базовых классов является индикатором для пользователя производного класса для создавая это только в куче (и мы просто надеемся на правильное использование класса) или мы можем иметь более надежную защиту от таких ошибок? Или я не понимаю некоторые моменты?
Пример кода:
класс C: общедоступный enable_shared_from_this
void func ()
{
C c;
shared_ptr
Таким образом, чтобы защититься от этой проблемы, вы можете сделать свои конструкторы приватными и предоставить только функции создания, которые возвращают shared_ptr - таким образом объект не может быть выделен в стеке, например:
class C : public enable_shared_from_this<C>
{
public:
static shared_ptr<C> create() { return shared_ptr<C>(new C() ); }
shared_ptr<C> method() { shared_from_this(); }
private:
C() {...}
// Make operator= and C(const C&) private unimplemented
// so the used cant do bad things like C c( * c_ptr );
C& operator=( const C & );
C( const C & );
};
void func()
{
C c; // This doesnt compile
shared_ptr<C> ptr = c.method(); // So you can never get this
}
void altfunc()
{
shared_ptr<C> c_ptr = C::create();
C & c_ref = *c;
shared_ptr<C> ptr = c_ref.method(); // OK
}
Если вы обнаружите, что хотите использовать anoperator=, вы можете предоставить функцию клонирования, используя частный реализованный конструктор копирования, что-то вроде этого
// This goes in class C
shared_ptr<C> C::clone() const
{
return shared_ptr<C>( new C(*this) );
}
// This is how you can use it
shared_ptr<C> c2 = c1->clone();