Reputation: 467
If I have a class A that contains a dynamically allocated instance of class B, does calling delete on a pointer to an instance of A (received from new of course) also effectively deallocate the memory occupied by the instance of B? Or does the destructor of A have to explicitly call delete on the instance of B in order for that to happen?
Upvotes: 0
Views: 293
Reputation: 168988
That depends on how you're storing the pointer to B
within the A
type.
class B;
class A {
private:
SomePointer m_b;
};
What is SomePointer
?
B*
then no, deletion of this B
allocation is not automatic. You would need to implement the destructor A::~A()
and delete it there. Don't forget to delete/implement the copy/move construction/assignment functions as well, or a copy/move operation will result in two A
s owning the same B
and that leads to (among other things) the double-free problem.std::unique_ptr<B>
then congratulations, you made the right choice and you don't have to do anything. A
's implicitly-defined destructor will destroy the std::unique_ptr<B>
which will delete the allocated B
for you. Additionally, the move constructor/assignment functions will be implicitly defined correctly (assuming the rest of the data members of A
are movable) and A
's copy operations will be implicitly deleted as they would be ill-formed (std::unique_ptr<B>
is not copyable).Here's an example of the two approaches. They both allow the same operations on A
. First, using a raw pointer:
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;
}
Now using std::unique_ptr<B>
:
class A {
private:
std::unique_ptr<B> m_b;
}
Which one would you rather maintain? Which one is easier to get right?
Upvotes: 3