A destructor gives an object its last rites.
Destructors are used to release any resources allocated by the object. E.g., class Lock might lock a semaphore, and the destructor will release that semaphore. The most common example is when the constructor uses new, and the destructor uses delete.
Destructors are a "prepare to die" member function. They are often abbreviated "dtor".
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
In reverse order of construction: First constructed, last destructed.
In the following example, b's destructor will be executed first, then a's destructor:
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
In reverse order of construction: First constructed, last destructed.
In the following example, the order for destructors will be a[9], a[8], ..., a[1], a[0]:
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
No.
You can have only one destructor for a class Fred. It's always called Fred::~Fred(). It never takes any parameters, and it never returns anything.
You can't pass parameters to the destructor anyway, since you never explicitly call a destructor (well, almost never).
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
No!
The destructor will get called again at the close } of the block in which the local was created. This is a guarantee of the language; it happens automagically; there's no way to stop it from happening. But you can get really bad results from calling a destructor on the same object a second time! Bang! You're dead!
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
No! [For context, please read the previous FAQ].
Suppose the (desirable) side effect of destructing a local File object is to close the File. Now suppose you have an object f of a class File and you want File f to be closed before the end of the scope (i.e., the }) of the scope of object f:
There is a simple solution to this problem. But in the mean time, remember: Do not explicitly call the destructor!
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
[For context, please read the previous FAQ].
Simply wrap the extent of the lifetime of the local in an artificial block {...}:
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
Most of the time, you can limit the lifetime of a local by wrapping the local in an artificial block ({...}). But if for some reason you can't do that, add a member function that has a similar effect as the destructor. But do not call the destructor itself!
For example, in the case of class File, you might add a close() method. Typically the destructor will simply call this close() method. Note that the close() method will need to mark the File object so a subsequent call won't re-close an already-closed File. E.g., it might set the fileHandle_ data member to some nonsensical value such as -1, and it might check at the beginning to see if the fileHandle_ is already equal to -1:
Note that the other File methods may also need to check if the fileHandle_ is -1 (i.e., check if the File is closed).
Note also that any constructors that don't actually open a file should set fileHandle_ to -1.
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
Probably not.
Unless you used placement new, you should simply delete the object rather than explicitly calling the destructor. For example, suppose you allocated the object via a typical new expression:
Then the destructor Fred::~Fred() will automagically get called when you delete it via:
You should not explicitly call the destructor, since doing so won't release the memory that was allocated for the Fred object itself. Remember: delete p does two things: it calls the destructor and it deallocates the memory.
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
There are many uses of placement new. The simplest use is to place an object at a particular location in memory. This is done by supplying the place as a pointer parameter to the new part of a new expression:
Line #1 creates an array of sizeof(Fred) bytes of memory, which is big enough to hold a Fred object. Line #2 creates a pointer place that points to the first byte of this memory (experienced C programmers will note that this step was unnecessary; it's there only to make the code more obvious). Line #3 essentially just calls the constructor Fred::Fred(). The this pointer in the Fred constructor will be equal to place. The returned pointer f will therefore be equal to place.
ADVICE: Don't use this "placement new" syntax unless you have to. Use it only when you really care that an object is placed at a particular location in memory. For example, when your hardware has a memory-mapped I/O timer device, and you want to place a Clock object at that memory location.
DANGER: You are taking sole responsibility that the pointer you pass to the "placement new" operator points to a region of memory that is big enough and is properly aligned for the object type that you're creating. Neither the compiler nor the run-time system make any attempt to check whether you did this right. If your Fred class needs to be aligned on a 4 byte boundary but you supplied a location that isn't properly aligned, you can have a serious disaster on your hands (if you don't know what "alignment" means, please don't use the placement new syntax). You have been warned.
You are also solely responsible for destructing the placed object. This is done by explicitly calling the destructor:
This is about the only time you ever explicitly call a destructor.
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
No. You never need to explicitly call a destructor (except with placement new).
A class's destructor (whether or not you explicitly define one) automagically invokes the destructors for member objects. They are destroyed in the reverse order they appear within the declaration for the class.
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
No. You never need to explicitly call a destructor (except with placement new).
A derived class's destructor (whether or not you explicitly define one) automagically invokes the destructors for base class subobjects. Base classes are destructed after member objects. In the event of multiple inheritance, direct base classes are destructed in the reverse order of their appearance in the inheritance list.
Note: Order dependencies with virtual inheritance are trickier. If you are relying on order dependencies in a virtual inheritance hierarchy, you'll need a lot more information than is in this FAQ.
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
Beware!!! See this FAQ for details.
[ Top | Bottom | Previous section | Next section | Search the FAQ ]
E-mail the author
[ C++ FAQ Lite
| Table of contents
| Subject index
| About the author
| ©
| Download your own copy ]
Revised Aug 15, 2001