问题
In c++, we love to do something in the destructor. But in what kind of situation, destructor will not be called?
Examples in the following cases:
exit()
call in the thread- unhandled exceptions and exit
TerminateProcess()
(in Windows)- warm/cold reboot computer
- sudden out of power of computer...
回答1:
This is one case every C++ programmer should know:
#include <stdio.h>
class EmbeddedObject {
private:
char *pBytes;
public:
EmbeddedObject() {
pBytes = new char[1000];
}
~EmbeddedObject() {
printf("EmbeddedObject::~EmbeddedObject()\n");
delete [] pBytes;
}
};
class Base {
public:
~Base(){
printf("Base::~Base()\n");
}
};
class Derived : public Base {
private:
EmbeddedObject emb;
public:
~Derived() {
printf("Derived::~Derived()\n");
}
};
int main (int argc, const char * argv[])
{
Derived *pd = new Derived();
// later for some good reason, point to it using Base pointer
Base* pb = pd;
delete pb;
}
~Base()
will be called but ~Derived()
will not. This means the code in ~Derived()
does not execute. It may have to do something important. Also it's EmbeddedObject
's destructor should have been automatically called but is not. Therefore, EmbeddedObject
does not get a chance to free its dynamically allocated data. This causes a memory leak.
Solution, make destructor in class Base
virtual
:
class Base {
public:
virtual ~Base() {
}
};
Making this one change to the above program means all destructors will be called in this oder: Derived::~Derived()
, EmbeddedObject::~EmbeddedObject()
, Base::~Base()
Read up on destructors in general. These kinds of problems are more likely to be something of concern to you than the other scenarios you mention. For example in the case of a power down, all bets for safe cleanup are usually off!
In C++ we have good control over enforcing the calling of destructors in the order we want them to happen, which is good news. However in the programs you write there is potential for your objects to be leaked and not deleted at all if you are not carefull enough.
回答2:
Destructors will not be called for objects outside the scope of an infinite loop.
回答3:
If you create an object with a placement new, the destructor for this object won't be called automatically.
回答4:
Appart from the obvious things mentioned i.e. exit(), kill signal, power failure etc.
There are some very common programming errors that would prevent the destructor being called.
1) A dynamic array of objects is created with
object* x = new object[n]
, but freed with delete x
instead of delete[] x;
2) Instead of calling delete() on an object you call free() instead. While memory is usually freed, the destructor will not be called.
3) Suppose you have an object hierarchy that should have declared virtual destructors but for some reason wasn't. If one of the subclass instances is cast to a different type in the heirarchy and then deleted, it may not call all the destructors.
回答5:
Throw an exception in another destructor that's being called because of a thrown exception.
来源:https://stackoverflow.com/questions/8733894/in-what-kind-of-situation-c-destructor-will-not-be-called