struct A {}
class B {
A *a;
public:
B () : a (new A) {}
~B() { delete a; }
};
class C {
A *a;
public:
C () : a (new A) {}
};
int main () {
delete new B;
delete new C;
}
分配 B 的一个实例然后删除是干净的,因为 B 在内部分配的内容也将在析构函数中被删除。
但是类 C 的实例将会泄漏内存,因为它分配了一个它不释放的 A 的实例(在这种情况下,C 甚至没有析构函数)。
A 的析构函数将在其生存期结束时运行。如果您希望释放它的内存并运行析构函数,那么如果它是在堆上分配的,则必须删除它。如果它是在堆栈上分配的,这将自动发生(例如,当它超出作用域时; 请参阅 RAII)。如果它是一个类的成员(不是指针,而是完整成员) ,那么当包含对象被销毁时就会发生这种情况。
class A
{
char *someHeapMemory;
public:
A() : someHeapMemory(new char[1000]) {}
~A() { delete[] someHeapMemory; }
};
class B
{
A* APtr;
public:
B() : APtr(new A()) {}
~B() { delete APtr; }
};
class C
{
A Amember;
public:
C() : Amember() {}
~C() {} // A is freed / destructed automatically.
};
int main()
{
B* BPtr = new B();
delete BPtr; // Calls ~B() which calls ~A()
C *CPtr = new C();
delete CPtr;
B b;
C c;
} // b and c are freed/destructed automatically
class B
{
public:
B()
{
p = new int[1024];
}
virtual ~B()
{
cout<<"B destructor"<<endl;
//p will not be deleted EVER unless you do it manually.
}
int *p;
};
class D : public B
{
public:
virtual ~D()
{
cout<<"D destructor"<<endl;
}
};
当你这样做:
B *pD = new D();
delete pD;
只有当基类具有 Virtual 关键字时,才会调用析构函数。
如果没有虚析构函数,那么只能调用 ~ B ()。但是因为您有一个虚析构函数,所以首先调用 ~ D () ,然后调用 ~ B ()。
除非您显式地删除它们,否则堆上分配的 B 或 D 的任何成员都不会被释放。删除它们也会调用它们的析构函数。