構造函數(constructor)不能被聲明為虛函數。
? 原因解釋
構造函數的主要職責是創建并初始化對象本身,而虛函數機制是基于 虛表指針(vptr) 的,它只有在對象構造完成之后才會起作用。
所以:
- 在構造函數執行過程中,虛函數機制還未建立完整的 vtable 結構;
- 此時如果構造函數是虛函數,無法進行多態調用;
- 因此,C++ 明確禁止構造函數聲明為
virtual
。
? 編譯器會報錯:
class Base {
public:virtual Base(); // ? 錯誤:構造函數不能是虛函數
};
錯誤信息大概會是:
error: constructors cannot be declared 'virtual'
? 那析構函數可以是虛函數嗎?
是的!而且 如果你打算通過基類指針刪除派生類對象,一定要把基類的析構函數設為 virtual
:
class Base {
public:virtual ~Base() { std::cout << "Base dtor\n"; }
};class Derived : public Base {
public:~Derived() { std::cout << "Derived dtor\n"; }
};int main() {Base* ptr = new Derived;delete ptr; // 正確調用 Derived 和 Base 析構函數
}
如果不設為虛析構,delete ptr
只會調用 Base::~Base()
,不會調用 Derived::~Derived()
,導致資源泄漏。
? 總結
特性 | 是否可以是虛函數 | 原因 |
---|---|---|
構造函數 | ? 不可以 | 構造階段對象未完整建立,vptr 不安全 |
析構函數 | ? 可以(推薦) | 支持通過基類指針釋放派生類對象,避免資源泄漏 |