在類的定義中,前面有virtual關鍵字的成員函數就是虛函數。多態是通過虛函數來實現的。
Class base{
Virtual int get();
};
Int base::get() { }
- Virtual 關鍵字只用在類定義里的函數聲明中,寫函數體時不用。
- 構造函數和靜態成員函數不能是虛函數
- 虛函數可以參與多態,而普通成員函數不可以。
多態的變現形式之一
- 派生類的指針可以賦給基類指針
- 通過基類指針調用基類和派生類中的同名虛函數時:
(1)若該指針指向一個基類的對象,那么被調用是基類的虛函數。
(2)若該指針指向一個派生類的對象,那么被調用的是派生類的虛函數。
這種機制就叫做多態。
多態的表現形式二
- 派生類的對象可以賦給基類引用
- 通過基類引用調用基類和派生類中的同名虛函數時:
(1)若該引用引用的是一個基類的對象,那么被調用的是基類的虛函數;
(2)若該引用引用的是一個派生類的對象,那么被調用的是派生類的虛函數。
這種機制也是多態。
多態的作用
在面向對象的程序設計中使用多態,能夠增強程序的可擴充性,即程序需要修改或增加功能的時候,需要改動和增加的代碼較少。
多態的常用方法
用基類指針數組存放指向各種派生類對象的指針,然后遍歷該數組,就能對各個派生類對象做各種操作,是很常用的做法。
在非構造函數,非析構函數的成員函數中調用虛函數是多態。
在構造函數和析構函數中調用虛函數不是多態,編譯即可確定,調用的函數是自己的類或基類中定義的函數。
派生類中和基類中虛函數同名同參數表的函數,不加virtual也自動成為虛函數。
測試代碼如下:
#include <iostream> #include <string> using namespace std; class A { private: int val; public: A(int val) :val(val) {}; virtual void addVal() { val += 10; cout << "A::addVal() is called" << endl; } void print() { cout << val << " "; cout << "hello world!" << endl; } }; class B :public A { private : string name; int value; public: B(string name, int value, int val) :A(val), name(name), value(value) {}; virtual void addVal() { value += 50; cout << value << " "; cout << "B::addVal() is called" << endl; } void print() { cout << name << endl; } void printHH() { cout << "HH" << endl; } }; int main() { A a(5); B b("chen", 8, 2); b.print(); A & a1=b; a1.addVal(); A *a2; a2 = &b; a2->addVal(); a2->print();//調用的是基類中的print函數。原因是當基類和繼承類中的函數名相同時,會優先調用自己類中的成員函數,a2是基類指針,屬於基類因此會調用基類的成員函數。b.print()是調用繼承類中的成員函數,因為b是繼承類。 return 0; }
參考鏈接:
https://www.coursera.org/learn/cpp-chengxu-sheji