如果我有一个包含动态分配的类B实例的类A,是否在指向A实例的指针(当然是从new接收到)的指针上调用delete也会有效地释放B实例所占用的内存?还是A的析构函数必须显式调用B实例上的delete才能使之发生?
答案 0 :(得分:1)
这取决于您如何在B
类型中存储指向A
的指针。
class B;
class A {
private:
SomePointer m_b;
};
什么是SomePointer
?
B*
,则为否,自动删除此B
分配是不是。您将需要实现析构函数A::~A()
并将其删除。不要忘记删除/实现复制/移动构造/分配功能,否则复制/移动操作将导致两个A
拥有相同的B
并导致(除其他外)东西)的双重自由问题。std::unique_ptr<B>
,那么恭喜您,您做出了正确的选择,而您无需做任何事情。 A
的隐式定义的析构函数将销毁std::unique_ptr<B>
,这将为您删除分配的B
。此外,将正确隐式定义move构造函数/赋值函数(假设A
的其余数据成员是可移动的),并且A
的复制操作将被隐式删除,因为它们将不正确。格式(std::unique_ptr<B>
不可复制)。这是这两种方法的一个例子。它们都允许对A
执行相同的操作。首先,使用原始指针:
class A {
public:
A();
// Need custom move logic.
A(A &&);
A & operator=(A &&);
// Prevent copying.
A(A const &) = delete;
A & operator=(A const &) = delete;
~A();
private:
B * m_b;
};
A::A() : m_b{nullptr} { }
A::~A() { delete m_b; }
A::A(A && other) : A{} { *this = std::move(other); }
A & A::operator=(A && other) {
using std::swap;
swap(m_b, other.m_b);
return *this;
}
现在使用std::unique_ptr<B>
:
class A {
private:
std::unique_ptr<B> m_b;
}
您想维持哪一个?哪个更容易正确?