If you think C++ is not overly complicated, just what is a protected abstract virtual base pure virtual private destructor and when was the last time you needed one? | ||
--Tom Cargill |
Since the responsibility for the initialisation of the class is in the hands of the
programmer of the class, the responsibility for the destruction of the class should also
be the responsibility of the programmer. In C++ we can write a destructor for a class that
performs some clean-up operations and even notifications. To define a destructor for a
class the ~ symbol is used in front of the class name, so for the Account
class you would use:
class Account{
// state definition
public:
Account(int theNumber, float theBalance);
virtual ~Account(); //destructor
// other member methods here.
};
Account::~Account()
{
cout << "Account object being destroyed!" << endl;
}
Note: A similar destructor is also written for the CurrentAccount
class.
The destructor must take no parameters and cannot return a result. A constructor cannot be virtual, but a destructor can (and should) be virtual (we will discuss this later).
When is a destructor called?
It is not invoked explicitly.
It is called when an object goes out of scope.
Suppose an object of the Account
class was created as below.
//main()
method whereCurrentAccount
is a child of theAccount
class, // with a destructor as defined just above. int main() { CurrentAccount b = CurrentAccount(50.0, 12345, 200.0); b.display(); }
The full source code for this example is listed in
AccountDestructor.cpp
What would happen? Since CurrentAccount
is a child of the
Account
class then destruction of an object of the CurrentAccount
object will result in the Account
destructor being called. When this example
is run you will get the output as in Figure 3.8, “The output from the Account Destructor Example.”.
In the Figure 3.8, “The output from the Account Destructor Example.” screen grab it can be seen that the
CurrentAccount
destructor followed by the
Account
destructor were called, just after the
main()
method ended, and just before the application ran to completion.
If you don't declare a destructor, C++ generates a default destructor, that frees up the memory of the object.
This is suitable for most classes, however a destructor may be required for specific actions:
Notifying other objects about an imminent destruction.
Closing open files, database connections, sockets etc.
Freeing dynamically allocated data. If an object does not free data that is dynamically allocated, then that memory will remain locked until the application terminates.
The problems with loosing dynamically allocated memory can be prevented from occurring by using the following structure:
class SomeClass{ // the states public: SomeClass(); virtual ~SomeClass(); //The destructor // other methods }; SomeClass::SomeClass(){ // Allocate extra space here in // the constructor! } SomeClass::~SomeClass(){ // De-allocate that extra space! }
In this case the programmer need only worry about freeing the extra space allocated in the constructor, not about the space for the object (or states) itself!
The destructor for the base class must be called when an object of a derived class is destroyed. This happens automatically! (in the order):
C++ calls the programmer defined destructor for the derived class.
C++ then calls the programmer defined destructor for the base class.
C++ then frees the object space itself.
This is the opposite way to how an object is constructed!
© 2006
Dr. Derek Molloy
(DCU).