虛擬函數允許子類覆蓋基類的函數,實現多態行為。它改變了對象模型,允許子類修改基類方法的實現。實戰案例中,shape 基類定義了 draw() 方法,而子類 rectangle 和 circle 覆蓋此方法以提供不同的繪制實現。好處包括多態性、代碼重用和設計靈活性。需要注意虛擬函數的運行時開銷、純虛函數的強制覆蓋以及靜態/動態綁定的謹慎使用。
C++ 虛擬函數與對象模型:深入理解面向對象設計
引言
虛擬函數是面向對象編程中的關鍵概念,它允許子類覆蓋基類的函數,實現多態行為。理解虛擬函數及其與對象模型的關系對于掌握面向對象設計至關重要。
虛擬函數
虛擬函數是在基類中聲明并由子類覆蓋的成員函數。當調用虛擬函數時,根據實際對象的類型而不是指向該對象的指針的類型,來調用覆蓋的函數。這使得子類可以提供自己的實現,而不需要修改基類。
在 C++ 中,通過使用 virtual 關鍵字聲明虛擬函數:
class Base {
public:
virtual void draw(); // 聲明虛擬函數
};
登錄后復制
對象模型
對象模型定義了對象在程序中的布局和行為。對象由數據和方法組成,其中方法是綁定到對象數據上的函數。虛擬函數的引入改變了對象模型,因為它允許子類修改基類方法的實現。
實戰案例:圖形繪制
考慮一個圖形繪制應用程序,其中有 Shape 基類和 Rectangle 和 Circle 子類。Shape 類定義了 draw() 方法,用于繪制形狀。子類覆蓋 draw() 方法以提供各自的繪制實現。
class Shape {
public:
virtual void draw() = 0; // 抽象基類,必須覆蓋
};
class Rectangle : public Shape {
public:
virtual void draw() override {
// 繪制矩形
}
};
class Circle : public Shape {
public:
virtual void draw() override {
// 繪制圓形
}
};
// 實例化子類并調用 draw() 函數
Shape* rectangle = new Rectangle();
rectangle->draw(); // 調用 Rectangle 的 draw() 方法
登錄后復制
好處
多態性:子類可以實現自己版本的方法,而無需修改基類。
代碼重用:基類可以提供通用實現,子類可以根據需要進行擴展。
設計靈活性:允許在不影響基類的前提下更改子類的行為。
注意事項
虛擬函數會產生運行時開銷,因此不要過度使用它們。
純虛函數(用 = 0 聲明)必須在派生類中覆蓋,否則該類將變為抽象類。
應小心使用靜態綁定和動態綁定(virtual 關鍵字),以避免對象切片和指針問題。






