在对象指针上调用 Delete 是否会递归删除其动态分配的成员



如果我有一个包含动态分配的类 B 实例的类 A,那么在指向 A 实例(当然是从新实例接收(的指针上调用 delete 是否也会有效地释放 B 实例占用的内存?还是 A 的析构函数必须在 B 的实例上显式调用 delete 才能发生这种情况?

这取决于您在A类型中存储指向B的指针的方式。

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。 此外,移动构造函数/赋值函数将被隐式正确定义(假设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;
}

你更愿意维护哪一个? 哪一个更容易得到正确?

最新更新