Чтобы инициализировать ссылочный член без ссылки на внешнюю сущность, переданную в конструктор содержащего класса, можно использовать метод фабрики, например:
struct B
{
B() : a(new_a()) {}
// factory
a& new_a()
{
A* a = new A;
return *a;
}
A& a;
};
Однако, конечно B::a
не будет уничтожен, когда B
Конец жизни, потому что это ссылка. Но нет доступа к B::a
вне B
, Так что это утечка памяти. Чтобы это исправить можно позвонить A::~A()
от B::~B()
B::~B() {a.~A();}
Но я читал, что вручную вызывать деструкторы было нет-нет, поэтому вызов A::~A()
в деструкторе B::~B()
падает или нет?
Есть ли более чистое решение?
delete &a;
в B
деструктор должен делать работу правильно, чтобы избежать утечки памяти.
Я бы лучше порекомендовал фабричную функцию, а должен возвращать std::unique_ptr<A>
хоть. Или вы просто используете простой экземпляр A
как B
Участник
Более чистым решением было бы избежать преобразования указателя в ссылку. Ссылка A& a;
член данных подразумевает, что struct B
не владеет объектом, который a
Рекомендации. Тем не менее, в вашем случае это так, и это создает путаницу.
Вы должны предпочесть ссылки (и необработанные указатели) для отношений, не являющихся владельцами, и интеллектуальные указатели или объекты-значения для владельцев отношений.
Например, std::unique_ptr<A> a;
член данных здесь четко показывает намерение владения, и в качестве бонуса, a
будет автоматически выпущен, когда B
уничтожен Вам даже не нужно ничего писать на ~B()
деструктор.
В результате ваш new a()
Функция может быть написана так:
std::unique_ptr<A> new_a() { return {new A()}; }
На самом деле вам не нужно писать new_a()
, Стандартная библиотека C ++ уже определяет для вас такую функцию: std::make_unique
,