要初始化引用成员而不引用传递给包含类的构造函数的外部实体,可以使用工厂方法,如下所示:
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()
会失败,还是会这样?
有更清洁的解决方案吗?
答案 0 :(得分:4)
答案 1 :(得分:1)
更清洁的解决方案是避免将指针转换为引用。引用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
。