I have a class with four member and no implemented Destructor by my part. If I delete the object, the 4 members will be deleted by the default destructor, right? If I make a blank custom destructor none of them will be deleted?If I make a custom destructor that only deletes one of them, will the other three be deleted as well?
-
Most of your assumptions are incorrect. A destructor always destroys an entire object. – Sam Varshavchik Jun 14 '22 at 00:17
-
3The four members will be destroyed when the class is destroyed, but if those members have unmanaged resources, for example they are raw pointers to dynamic allocations, either those members need to be replaced with classes that do manage the resources or the class being destroyed needs a much smarter destructor to manage those resources (as well as needing more functions to ensure they are properly copied and moved). – user4581301 Jun 14 '22 at 00:18
-
3Regardless of if you provide a destructor or not, a class' members are destroyed at the end of its lifetime. If you provide a destructor, that happens after the destructor finishes. You only need a destructor if you *need* to do something special in addition to this, such as `delete`ing a pointed object. But normally, with a well implemented class using RAII, you don't need a destructor. – François Andrieux Jun 14 '22 at 00:19
-
@FrançoisAndrieux So, in case the four attributes are pointers to `new` objects I need to deal with them explicitly, since the lifetime didn't end and a empty destructor would do nothing about them? – Roman Jun 14 '22 at 00:23
-
1Correct, you will need to provide a destructor and `delete` them yourself to free the memory. Generally, you should avoid using `new`, and you can instead rely on `unique_ptr` or `shared_ptr` for memory management. – ChrisMM Jun 14 '22 at 00:30
-
If something is `new`ed, at some point, it must be `delete`d, otherwise there's a memory leak. – Sam Varshavchik Jun 14 '22 at 00:30
-
I would recommend the “c++ in depth” series. – Taekahn Jun 14 '22 at 00:31
-
Don't just focus on pointers. They are the easiest example for this kind of problem, but it extends to any and all resources. Say the class holds a file handle or network socket, you will want to close the handle or socket in the destructor. Getting outside of software and into the real world, you may have a rotor that needs to stop or robot arm than needs to be reset to a safe position. – user4581301 Jun 14 '22 at 00:33
-
The real kicker is to manage that resource as close to the resource as possible. Sometimes that means you create a new class that does nothing but acquire, release and safely copy (or deny copying) a resource. This allows other classes that use that protected resource to be simpler because they no longer have to be responsible for it. This is summed up in [the concept of RAII](https://stackoverflow.com/questions/2321511/what-is-meant-by-resource-acquisition-is-initialization-raii) mentioned in an earlier comment. – user4581301 Jun 14 '22 at 00:38
1 Answers
Strictly answering your questions
I don't think that answering your question actually helps you because the way you framed the problem doesn't help you. But here it is anyway:
If I delete the object, the 4 members will be deleted by the default constructor, right?
Right
If I make a blank custom destructor none of them will be deleted
Incorrect. Still all the members will be properly deleted.
If I make a custom destructor that only deletes one of them, will the other three be deleted as well?
A destructor (nor any method) cannot legally explicitly delete its own members.
Addressing your confusion
If p
is a pointer, when you do delete p
you are not deleting the pointer p
, you are deleting the object pointed by p
. p
is there to tell you what object needs deletion. After delete p
p
is still alive. Sure it points to invalid memory, but it itself is not deleted. You can assign to it and make it point to something else.
Let's consider a simple class with 3 members: a float, an int pointer, and a std::vector
object:
struct X
{
float f;
int* p;
std::vector<double> v;
};
The 3 members of your class are: a float, a pointer and std::vector
object. These members will always get properly destroyed by the destructor, regardless if you have a user defined destructor or a implicit destructor. Always! All members! No exception. You cannot inhibit or modify this behavior in any way.
For f
I don't think there is anything to explain.
Now for the interesting part: p
here you need to see a very important distinction: the pointer p
(which is your data member) and the potential int object that is pointed by p
. Like any other data members, the pointer p
will properly be disposed by the destructor.
But what should happen to the object that is pointed by the pointer p
? Well there are several cases: your pointer might point to an int object, to null, be uninitialized or point to an invalid address. If it points to an int object it might point to an int object that is a subobject of another class type, it might be an element in an array, it might be an static object or an object with automatic storage duration or it might be an int object created by new
. If it is created by new
it might be the X
class responsibility to delete it or not and there might be a complex decision if it must destroy it (think shared pointers). X
should delete the object pointed by p
iff X
has ownership over this pointer and a proper logic should be implemented.
As you can see the complier cannot possibly know to what p
points to and if X
should delete it. That's why the default destructor doesn't do it.
For v
again, the destructor (default or user defined) will properly destroy v
. You might now that internally std::vector
has a pointer member of its own, but: it's std::vector
's responsibility to destroy the array that pointer might point to, not X
. It all works out of the box, X
does not need to do anything special.
How you should think about it
In C++ there is the RAII principle which, despite its poor name it is one of the most important concepts in C++. Basically if your class acquires a resource that needs manual management then that class has ownership over that resource and is it responsible to release that resource. So if your class does manual memory allocation (new
) then it is responsible to call the corresponding delete
. If it acquires a resource by a fictitious resource_aquire()
then it is the one responsible to also call the accompanying resource_destroy()
Another important principle is the single responsibility principle: if your class is responsible with managing a resource then that class should do only that thing.

- 72,283
- 15
- 145
- 224