Virtual Function
(1)Pure virtual function :指明某個函式只提供一個介面,要求繼承的子類別要重新定義子函式
擁有pure virtual function 的class才稱為abstract class(抽象類別)
- abstract class-該類別只能被繼承,不能用此產生實例
#ifndef ABSTRACTCIRCLE #define ABSTRACTCIRCLE class AbstractCircle { public: void radius(double radius) { _radius = radius; } double radius() { return _radius; } // 宣告虛擬函式 virtual void render() = 0;"其中此函式必須在subclass中定義" protected: double _radius; }; #endif
(2)Virtual function:一個介面,多種函式
擁有virtual function的class稱為polymorphic class(多型類別)
名詞解析:
- redefinition(重訂):衍生類別中,定義一個跟基礎類別相同名稱的函數,稱為 redefinition
- overidding(覆寫、覆蓋):而如果重訂的對象是虛擬函數,那可稱為 overidding
- object slicing(物件遭切割):函數傳遞變數(基礎類別)的方式採用 by value 的話,會被切掉衍生類別的相關資料
C++11為了避免子函式莫名pass調virtual function,為此定義override機制
class CA
{
public:
virtual void func1(int)
{
std::cout << “func1 in CA" << std::endl;
}
};
class CB : public CA{ public: void func1(int) const override "同名而卻沒有覆蓋,就成為編譯錯誤的基準" { std::cout << “func1 in CB" << std::endl; } };class CC : public CA{public: void func1(float) override { std::cout << “func1 in CC" << std::endl; } };
- 尾部加上final用來避免虛擬函數被覆蓋,基底函數被繼承
(4) VPTR
基礎類別中有虛擬函數時 編譯器會幫這些基礎類別衍生類別內的同名函數加上 VPTR 來識別
(5) VTABLE
編譯器還為每個類別加上一個VTABLE,VPTR指向VTABLE的開頭。 VTABLE 紀錄了基礎類別內被宣告為 virtual function 的成員函數。
- 基礎類別的 VTABLE 就是紀錄自己的成員函數。
- 衍生類別內,假如自己有overriding 基礎類別的virtual function ,那就會儲存衍生類別的成員函數的位址。
- 如果沒overidding,那就儲存基礎類別的成員函數的位址。
- 所以VPTR、VTABLE 就是幫助late binding
虛擬解構函數
建構時,還沒編排 VPTR VTABLE,所以不必在意。
但解構時必須把解構函數宣告成virtual function ,才能釋放 VPTR VTABLE
像這樣: virtual ~base()
反正,基礎類別內有宣告虛擬,那你就把解構也虛擬,就可以了。否則記憶體可能會一直沒有釋放, memory leakage 洩漏到無法使用之處。
沒有留言:
張貼留言