2016-09-15 10 views
0

У меня есть класс A, который предоставляет методы для построения экземпляров класса B. И B содержит личную ссылку на A и предоставляет конструктор для установки этой ссылки.Время жизни зависимых классов в C++?

class A { 
    public: 
    B* construct_B(); 
} 
class B { 
    private: 
    const A& private_A; 
    public: 
    B (const A& my_A): private_A (my_A) { } 
} 

Реализация construct_B заботится о динамическом распределении и передавая ссылку на себя через this.

Как реализовать эту настройку таким образом, чтобы я был уверен, что время жизни A больше, чем B, так что его ссылка остается в силе? Заметьте, что я не забочусь обо всех возможностях construct_B вместо того, чтобы возвращать необработанный указатель, я мог бы вернуть умный указатель или аналогичный.

Одним из возможных путей решения это может быть с B вместо того чтобы держать ссылку держать смарт-указатель на A, и вместо динамического выделения B в construct_B принять статическую ссылку на B, а затем установить его указатель, что-то вроде

class A : 
    public std::enable_shared_from_this<A> { 
    public: 
     void setup_B (const B& my_B) { 
     my_B.set_A (shared_ptr_from_this()) ; 
} 
class B { 
    private: 
    const shared_ptr<A> private_A_ptr; 
    public: 
    void set_A (const shared_ptr<A> my_A): 
     private_A_ptr (my_A) { } 
} 

, которые затем могут быть реализованы с помощью Int основной() { A static_A; B static_B; A.setup_B (static_B); }

Удаляет ли shared_ptr этой последней конструкции проблему A, удаляемую до B?

+0

Почему бы вам не попробовать и не сделать консольный выход? Но здесь A будет удален только тогда, когда никто больше не указывает на A. – Hayt

+1

«Предоставляет ли shared_ptr этой последней конструкции проблему удаления A перед B? ' да, это так. Единственное предостережение в том, что сам А должен принадлежать shared_ptr, иначе shared_from_this() будет UB. –

ответ

2

shared_ptr - ваш ответ. Что-то вроде этого:

#include <memory> 

struct A; 

class B { 
    const std::shared_ptr<A> private_A_ptr; 
    public: 
    B(std::shared_ptr<A> parent) : private_A_ptr(std::move(parent)) {} 
}; 

struct A : 
std::enable_shared_from_this<A> 
{ 
    B make_b() { 
    return B(shared_from_this()); 
    } 
}; 

int main() 
{ 
    // this would be invalid: 
    //A a; 
    //auto b = a.make_b(); 

    // but this is fine 

    auto pa = std::make_shared<A>(); 
    auto b = pa->make_b(); 

    // later... 
    pa.reset(); 

    // A still exists because ownership was shared with b 

}