Это не простой случай, когда говорят «используйте умные указатели». B, кажется, является фабрикой A. У A есть указатель на фабричный объект, который его создал (и предположительно может создавать из него больше объектов A-типа).
Если вы хотите, чтобы B подсчитывался по ссылке, он должен быть "навязчиво" подсчитан по ссылке. Обычно это делается с помощью какого-то механизма addRef () / release (), и когда в последний раз вызывается release (), обычно выполняется удаление this
Я мог бы также предположить, что A в некотором роде полиморфен, так что вы можете получить объект для создания большего количества объектов его собственного типа (не обязательно клонов) через его абстрактную фабрику.
Вопрос в том, откуда появился первый B, который создал первый A? Есть ли у вас много этих объектов B, и вы действительно хотите избавиться от них в тот момент, когда ваш последний объект A удален, или его временем жизни управляют в другом месте.
Что касается A, ваш B создаст новый с обычным новым, а затем вы положите его в shared_ptr или что-то еще.
Обратите внимание, что вы можете использовать ссылку здесь, например:
class A
{
private:
friend class B;
explicit A( B const& b );
B (const) & b_;
A(const A&); // not implemented
public:
A* createNew() const;
~A();
};
A::A( B const& b )
: b_( b )
{
b_.addRef(); // possibly, if reference counted
}
A::~A()
{
b_.release();
}
A* A::createNew() const
{
return b_.createA();
}
для B
A* B::createNew() const
{
return new A(*this); // addRef() will be invoked
}
void B::addRef() const
{
atomically_increment( &my_refCount );
}
void B::release() const
{
if( !atomically_decrement( &my_refCount ) )
delete this;
}
где B имеет изменяемый тип my_refCount, который подходит для атомного вызова увеличения / уменьшения для вашей системы.
Обратите внимание, что вы также можете использовать boost shared_ptr для B, но для этого потребуется извлечь B из boost::enable_shared_from_this<B>
. Это также «навязчиво», но сделает большую работу за вас. Теперь вашему A нужно будет хранить boost::shared_ptr<B>
, а B :: createA () будет вызывать shared_from_this()
.
Чтобы сделать это таким образом, вам нужно будет создать свой первый B и поместить его в shared_ptr для создания первого A.