虛擬函式與多型

study_all_day發表於2024-04-18

虛擬函式

  • 前有 virtual 關鍵字的成員函式
class base{
	virtual int get();
}
int base::get{}
  • virtual關鍵字只用在類的定義裡的函式宣告
  • 建構函式與靜態成員函式不能是虛擬函式

多型

表現形式 一

  • 派生類的指標可以賦給基類的指標
  • 透過基類指標呼叫基類和派生類中的同名虛擬函式
    • 指向基類的物件,呼叫基類的虛擬函式
    • 指向派生類,呼叫派生類的虛擬函式

表現形式 二

  • 派生類的指標可以賦給基類引用

  • 透過基類引用呼叫基類和派生類中的同名虛擬函式

    • 引用的是基類的物件,呼叫基類的虛擬函式
    • 引用的是派生類物件,呼叫派生類的虛擬函式
  • 在非建構函式和非解構函式的成員函式中呼叫虛擬函式,就是多型

  • 在建構函式與解構函式中呼叫虛擬函式,在編譯時即可確定,呼叫的函式時自己的類或基類中定義的函式

多型的實現

依靠動態聯編

虛擬函式表

  • 每一個有虛擬函式的類都有虛擬函式表,該類的任何物件中都放著虛擬函式表的指標。
  • 4個位元組

虛解構函式,純虛擬函式和抽象類

虛解構函式

  • 把基類的解構函式宣告為virtual
  • 透過基類的指標刪除派生類的物件時,首先呼叫派生類的解構函式,然後呼叫基類的解構函式
    ![[Pasted image 20231227154139.png]]
    ![[Pasted image 20231227154156.png]]

純虛擬函式和抽象類

純虛擬函式:沒有函式體的虛擬函式

class A{
	private: int a;
	public:
		virtual void Print()=0; //純虛擬函式
		void fun(){cont<<"fun";}
}

抽象類:包含純虛擬函式的類

  • 只能作為基類來派生新類使用,不能建立派生類的物件
  • 抽象類的指標和引用可以指向由抽象類派生出來的類的物件
    • A * pa;
  • 抽象類的成員函式內可以呼叫純虛擬函式(不包括建構函式或解構函式)
  • 如果一個類從抽象類派生而來,那麼當且僅當他實現了基類中所有的純虛擬函式,他才能成為非抽象類

相關文章