Я видел, что полезным способом написать метод клона, который возвращает boost :: shared_ptr, является выполнение
class A
{
public:
shared_ptr<A> Clone() const
{
return(shared_ptr<A>(CloneImpl()));
}
protected:
virtual A* CloneImpl() const
{
return(new A(*this));
}
};
class B : public A
{
public:
shared_ptr<B> Clone() const
{
return(shared_ptr<B>(CloneImpl()));
}
protected:
virtual B* CloneImpl() const
{
return(new B(*this));
}
};
Это позволяет использовать ковариацию с обычным указателем, в то же время сохраняя его в безопасности интеллектуального указателя. Моя проблема в том, что мой класс B должен унаследовать от boost :: enable_shared_from_this, потому что сразу после построения ему нужно зарегистрировать себя в отдельном классе, передав общий указатель на себя. У меня есть метод Create, который оборачивает конструкцию и регистрацию, чтобы они всегда происходили вместе. Однако приведенная выше реализация метода клона не может удовлетворить это требование. Регистрация не может происходить в CloneImpl, так как еще не существует shared_ptr, «владеющего» объектом, предотвращающего вызов shared_from_this (), и если эта логика отсутствует в виртуальной функции, то shared_ptr, который указывает на B, не знает о потребностях B в регистрации когда клонировали. Как лучше всего решить эту проблему?