基類指針指向派生對象,delete 時若基類析構函數非虛,只會調用基類析構,導致派生類資源未釋放(內存洩露)。
class A { public: ~A() { cout << "A dtor\n"; } };
class B : public A { public: ~B() { cout << "B dtor\n"; } };
int main() {
A* p = new B();
delete p; // 輸出:A dtor (B dtor 未調用!)
}
delete p 編譯期根據靜態類型 A* 決定調用 A::~A()。派生類析構函數不被調用,其中的 delete[]、fclose、unlock 等清理代碼全失效。
class A { public: virtual ~A() { cout << "A dtor\n"; } };
class B : public A { public: ~B() { cout << "B dtor\n"; } };
int main() {
A* p = new B();
delete p; // 輸出:B dtor → A dtor (正確!)
}
virtual ~A() 使析構函數成為虛函數,編入虛函數表delete p 時編譯器生成代碼:查詢對象動態類型的虛表,調用對應析構函數unique_ptr/shared_ptr)管理生命週期,避免手動 delete每個含虛函數的類對象增加一個指針(vptr),每個類增加一張虛表。對於大量小對象可能有內存開銷,但正確性優先。