虛函數是 C++ 實現執行期多型的核心機制。理解其在基類與衍生類之間的覆寫、隱藏、轉換規則,對於正確設計類別階層至關重要。
virtual)override (C++11) 讓編譯器檢查簽章一致性若衍生類別定義同名但參數不同的函數,會隱藏基類所有同名虛函數,而非覆寫:
class Base {
public:
virtual void fcn(int) { cout << "Base::fcn(int)" << endl; }
virtual void fcn() { cout << "Base::fcn()" << endl; }
};
class Derived : public Base {
public:
void fcn(double) { cout << "Derived::fcn(double)" << endl; } // 隱藏基類所有 fcn
};
int main() {
Derived d;
d.fcn(3.14); // 呼叫 Derived::fcn(double)
// d.fcn(1); // 編譯錯誤:基類 fcn(int) 被隱藏
// d.fcn(); // 編譯錯誤:基類 fcn() 被隱藏
}
解決方法:使用 using Base::fcn; 引入基類名稱。
衍生類別物件可隱性轉換為基類指標或參考,透過虛函數表實現動態繫結:
class Base {
public:
virtual int fcn() { cout << "Base::fcn()" << endl; return 0; }
};
class Derived : public Base {
public:
int fcn() override { cout << "Derived::fcn()" << endl; return 1; }
};
int main() {
Derived d;
Base* pb = &d; // 向上轉換
Base& rb = d;
pb->fcn(); // 輸出:Derived::fcn() - 動態繫結
rb.fcn(); // 輸出:Derived::fcn()
}
/* cppprimer.cpp
* Created on: 2013.11.13
* Author: Caroline
* Compiler: eclipse cdt, gcc 4.7.1
*/
#include <iostream>
using namespace std;
class Base {
public:
virtual int fcn() { // 虛函數
cout << "This base class [int fcn()]. " << endl;
return 0;
}
virtual void fcn(int) { cout << "Base::fcn(int)" << endl; }
};
class Derived : public Base {
public:
int fcn() override { // 覆寫
cout << "Derived::fcn()" << endl;
return 1;
}
// void fcn(double) { ... } // 若啟用會隱藏基類所有 fcn
};
int main() {
Base b;
Derived d;
Base* pb = &d;
pb->fcn(); // 動態繫結:Derived::fcn()
pb->fcn(42); // 靜態繫結:Base::fcn(int) (Derived 未覆寫)
return 0;
}
覆寫函數回傳型別可為基類回傳型別的衍生類別(指標/參考):
class Base {
public:
virtual Base* clone() { return new Base(*this); }
};
class Derived : public Base {
public:
virtual Derived* clone() override { return new Derived(*this); } // 共變返回
};
override、final (C++11) 增強程式碼安全性