When is it essential that a class have to define a destructor in C++ class and why?
Just starting to learn this in C++ and need it to be clarified.
When is it essential that a class have to define a destructor in C++ class and why?
Just starting to learn this in C++ and need it to be clarified.
You only need to define a destructor if your class needs to do special cleanup, such as freeing dynamically allocated memory.
You need to define a destructor when you have dynamically allocated memory. A good rule of thumb is if you use new in any of your constructors you probably need a destructor. Anything that isn't automatic storage or static storage is considered dynamically allocated
Anything that would fall under the category of cleaning up is appropriate to put in a destructor for example closing a network connection
There might be other reasons, but the first one i'm thinking of is that some of your class attributes might need to be explicitely freed.
if your class simply have, say, two int attributes, then those will be deleted along with your object automatically when you call delete myObject
. But if it includes any dynamically allocated attribute, those won't be freed along with your object, so you'll need to explicitely delete them in your destructor.
You only have to define a destructor if the default behavior of the destructor is not what you want.
When an object is destroyed, the destructor does these things, whether you define a custom destructor or not:
This actually handles most things that you might want to do. It used to be common to define a custom destructor when memory was allocated in the constructor:
struct A {
B *b_ptr;
A() : b_ptr(new B) { }
~A() { delete b_ptr; }
};
But when you are using standard containers and smart pointers, the number of cases where you need a custom destructor are relatively small. For example, if you have a class like this
struct A {
std::unique_ptr<B> b_ptr;
A() : b_ptr(new B) { }
};
there is no need to define your own destructor, since the std::unique_ptr will free the allocated memory. Likewise, there is no need to define a destructor here
struct B {
ifstream input_stream;
B(const std::string &path) : input_stream(path) { }
};
since the input_stream
will automatically be closed when the input_stream member is destroyed.
From time to time, there are cases where you need to do something special though. You need a special call to acquire or release a resource. In that case, you want to have a destructor:
struct C {
ResourceHandle resource_handle;
C() : resource_handle(resouce_manager.acquireResource()) { }
~C() { resource_manager.releaseResource(resource_handle); }
};
But as much as possible, you want to localize this kind of behavior so that it doesn't have to be duplicated in many classes. For example, you might want to make class like this:
struct ResourceHolder {
ResourceHandle resource_handle;
ResourceHolder() : resource_handle(acquireResource()) { }
~ResourceHolder() { releaseResource(resource_handle); }
};
Now you can just use a ResourceHolder within each class that needs one of these resources, and you never have to repeat the acquire and release logic again.
A destructor is not only used to free memory allocated, for instance, in the constructor.
You can achieve RAII-style functionality by using a destructor.
Example of types that take advantage of this:
std::fstream
closes opened files
std::lock_guard
unlocks a mutex
std::shared_ptr
decrements a reference counter or free the memory if the counter is 0.
There are 2 instances that you need to define a destructor: