When we are developing modern applications, we construct many objects by using our classes, they normally deconstruct themself when they are out of scope, sometimes we need operations to deconstruct them which means we need to define destructors. Destructors are not only used in classes but also used with struct and union data types. In this post, we will try to explain how to use a Typical Destructor in Classes with given examples.
Table of Contents
What is a constructor in C++?
The Constructor in C++ is a function, a method in the class, but it is a ‘special method’ that is automatically called when an object of a class is created. We don’t need to call this function. Whenever a new object of a class is created, the Constructor allows the class to initialize member variables or allocate storage. This is why the name Constructor is given to this special method. Here is a simple constructor class example below.
1 2 3 4 5 6 7 8 9 10 |
class myclass { public: myclass() { std::cout << "myclass is constructed!\n"; }; }; |
What is a destructor in C++?
The Destructor in classes (i.e class_name
) is a special member function to delete objects, in other terms it is called when the lifetime of an object ends. The purpose of the destructor is to do operations when destruct the object. The object may have acquired or allocated data on memory on runtime, they need to be freed too when objects are being deleted, destructor is the function that frees the resources of the object. When we construct an object, sometimes we need operations to deconstruct. Destructors are not only used in classes but also used with struct and union data types.
1 2 3 4 5 6 7 8 9 10 |
class myclass { public: ~myclass() // Destructor { }; }; |
What are the types of destructors in modern C++?
1. Typical Declaration of a Destructor
The Destructor in classes (i.e class_name)
is a special member function to delete objects, in other terms it is called when the lifetime of an objects ends. The purpose of the destructor is to do operations when destruct the object. Object may have acquired or allocated data on memory on runtime, they need to be freed too when objects are being deleted, destructor is the function that free the resources of object.
To define a destructor in a class we use ‘~‘ symbol with the same class name and parenthesis as given below,
Syntax,
1 2 3 |
~ class_name (); |
Destructor declaration example in a class.
1 2 3 4 5 6 7 8 9 10 |
class myclass { public: ~myclass() // Destructor { }; }; |
If you want to learn more details about this type with a full C++ example, please follow this post.
2. Virtual Destructor
in C++The Destructor in classes (i.e. class_name) is a special member function to delete objects, in other terms it is called when the lifetime of an objects ends. The purpose of the destructor is to do operations when destruct the object. Object may have acquired or allocated data on memory on runtime, they need to be freed too when objects are being deleted, destructor is the function that free the resources of object.
Virtual Destructor is usually required in a base class, and it is used by the class which has this base class. Note that, deleting a class object through pointer to base invokes undefined behavior unless the destructor in the base class is virtual:
Syntax,
1 2 3 |
virtual ~class_name (); |
Virtual destructor declaration example in a class,
1 2 3 4 5 6 7 8 9 10 |
class myclass { public: virtual ~myclass() // Virtual Destructor { }; }; |
If you want to learn more details about this type with a full C++ example, please follow this post,
3. Pure Virtual Destructor
A Virtual Destructor is usually required in a base class, and it is used by the class which has this base class and described in previous section.
A Pure Virtual Destructor is defined in a base class with =0; statement, and its body is declared outside of the class. Pure Virtual Destructors are mostly used in C++ standard and it is generally used in libraries (dynamic DLL or static)although there are use cases for virtual destructors. Note that, if your class contains a pure virtual destructor, it should provide a function body for the pure virtual destructor. If you are asking why a pure virtual function requires a function body the answer is destructors are not actually overridden, rather they are always called in the reverse order of the class derivation. That means, firstly a derived class destructor will be invoked, and then the base class destructor will be called. If the definition of the pure virtual destructor is not provided, then the compiler and linker enforce the existence of a function body for pure virtual destructors.
Syntax,
1 2 3 |
virtual ~class_name () = 0; |
Virtual destructor declaration example in a class.
1 2 3 4 5 6 7 8 |
class myclass { public: virtual ~myclass() = 0; // Pure Virtual Destructor }; |
If you want to learn more details about this type with a full C++ example, please follow this post.
4. Forcing a Destructor (Forced Destructor, Defaulted Destructor)
Defaulted destructors can be declared with = default; term at the end that means it is forcing a destructor to be generated by the compiler.
Syntax,
1 2 3 |
~class_name () = default; |
1 2 3 |
<decl-specifier> ~ class_name () = default; |
Forcing a destructor to be generated by the compiler.
1 2 3 4 5 6 7 |
class myclass { public: ~myclass() = default; // Defaulted Destructor, Forcing Destructor }; |
If you want to learn more details about this type with a full C++ example, please follow this post.
5. Deleted Destructor, (Disabling The Implicit Destructor, Deleted Implicit Destructor)
Since C++11 a class type can be defined as deleted by using = delete
. This can be a implicitly-declared or explicitly-defaulted destructor. Here is how we can use it.
1 2 3 |
~class_name () = delete; |
Syntax,
1 2 3 |
<decl-specifier> ~class_name () = delete; |
1 2 3 4 5 6 |
class my_class { public: ~my_class() = delete; // Destructor that is deleted }; |
In other words, the destructor can be disabled by the = delete; statement for the Implicit Destructor Declaration. Disabling the Implicit Destructor a destructor to be generated by the compiler.
1 2 3 4 5 6 7 |
class myclass { public: ~myclass() = delete; // Disabling The Implicit Destructor }; |
If you want to learn more details about this type with a full C++ example, please follow this post.
6. Implicitly-Defined Destructor
An implicitly defined destructor is a destructor method with a body generated and compiled and it is not deleted. If a destructor declared and it is not deleted, it can be implicitly defined by the compiler when it is used by other classes. This implicitly defined destructor may have an empty body. If this satisfies the requirements of a constexpr_destructor
, the generated destructor is constexpr
In this example below, the implicitly defined destructor is called in the main function from the class1 to destroy the class1, as you see it is declared in my_class
and can be implicitly used from the my_otherclass
Here is an example of an Implicitly-Defined Destructor
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
class my_class { public: ~my_class() // Destructor { std::cout << "Class has been destructed\n"; }; }; class my_otherclass { public: my_class test; // This class has Implicitly-Defined Destructor }; |
If you want to learn more details about this destructor type with a full C++ example, please follow this post.
7. Implicitly-Declared Destructor
An implicitly-declared destructor is a destructor method in a class and If there is no declared destructor that is provided in a class (struct, class, or union), the compiler declares a destructor itself as an inline public
member of its class,
As with any implicitly declared special member function, the exception specification of the implicitly declared destructor is non-throwing unless the destructor of any potentially constructed base or member is potentially throwing implicit definition would directly invoke a function with a different exception specification, until C++17. In practice, implicit destructors are noexcept
unless the class is “poisoned” by a base or member whose destructor is noexcept(false)
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
class my_class { public: ~my_class() // Destructor { std::cout << "Class has been destructed\n"; }; }; class my_otherclass : my_class { public: // This class has Implicitly-Declared Destructor }; |
If you want to learn more details about this destructor type with a full C++ example, please follow this post.
8. Deleted Implicitly-Declared Destructor
The implicitly-declared or defaulted destructor for the class is a destructor method that it is defined as deleted since C++11. To say that is a Implicitly Declared Destructor, any of the following below should be maintained,
- The class has a non-static data member that cannot be destructed
- The class has direct or virtual base class that cannot be destructed
- The class is a union and has a variant member with non-trivial destructor
also note that,
- If the base class has a virtual destructor then implicitly-declared destructor is virtual
- A defaulted prospective destructor for the class is defined as deleted if it is not the destructor for that class
According to open-std.org resource, any direct or virtual base class or non-static data member has a type with a destructor that is deleted or inaccessible from the defaulted default constructor or default constructor.
Here is an Implicitly-Declared Default Constructor example that gives an Error.
1 2 3 4 5 6 7 8 9 10 11 12 |
class my_class { public: ~my_class() = delete; // Destructor that is deleted }; class my_otherclass : public my_class { public: // This class has Deleted Implicitly-Declared Destructor }; |
If you want to learn more details about this destructor type with a full C++ example, please follow this post,
9. Trivial Destructor
In C++, normally all base classes have trivial destructors and all non-static data members of class type have trivial destructors. A destructor of a class is trivial if,
- It is not implicitly declared, or explicitly defined as defaulted on its first declaration, means it is not user provided.
- It is not virtual and the base class destructor is not virtual.
For example,
1 2 3 4 5 |
class my_class { public: // This class has a trivial destructor as a default }; |
10. Prospective Destructor
Since C++20, prospective destructors are special member functions of that class. We may have one or more prospective destructors and we can select one of them as a destructor. At the end of the definition of the class, we can determine which prospective destructor is the destructor, to do this overload resolution is performed between these defined prospective destructors.
C++ Builder is the easiest and fastest C and C++ compiler and IDE for building simple or professional applications on the Windows operating system. It is also easy for beginners to learn with its wide range of samples, tutorials, help files, and LSP support for code. RAD Studio’s C++ Builder version comes with the award-winning VCL framework for high-performance native Windows apps and the powerful FireMonkey (FMX) framework for UIs.
There is a free C++ Builder Community Edition for students, beginners, and startups; it can be downloaded from here. For professional developers, there are Professional, Architect, or Enterprise versions of C++ Builder and there is a trial version you can download from here.
Design. Code. Compile. Deploy.
Start Free Trial
Free C++Builder Community Edition