多態性
多態性是面向對象程序設計的重要特性
一種接口,多種方法
在C++程序設計中,多態性是指具有不同功能的函數可以使用同一個函數名。
在面向對象方法中多態性一般表述為:向不同的對象發送同一個消息,不同的對象在接收時會產生不同行為。
多態性可分為:靜態多態性和動態多態性
靜態多態性(編譯多態性):在程序編譯時系統就能決定調用哪個函數,通過重載實現(包括函數的重載、運算符的重載)。
動態多態性(運行多態性):在程序運行的時候才動態的確定操作所針對的對象,通過虛函數實現。
虛函數
在同一個類中不能定義兩個名字相同、參數類型及個數都相同的函數,否則就是“重復定義”(多重繼承下來兩個完全相同的不算重復定義)。而在繼承層次結構中,不同層次中可以出現名字、參數類型、參數個數都相同的函數,因為在不同層次中編譯系統會按照同名屏蔽的原則調用派生類的函數。
特別說明:析構函數也可以為虛,實現原理相同(虛函數表實現),但構造函數不能為虛,因為指向vtable的指針其實是存儲在對象的內存空間的。問題出來了,如果構造函數是虛的,就需要通過 vtable來調用,可是對象還沒有實例化,也就是內存空間還沒有,怎麼找vtable呢。
譚浩強版本中:虛函數的作用是允許在派生類中重新定義與基類同名的函數,並通過基類指針或引用來訪問基類和派生類中的同名函數。
個人覺得前半句不妥,即無虛函數仍可以在派生類中重新定義與基類同名的函數,舉例說明:
class A
{
public:
void ss()
{cout<<"hello"<<endl;}
};
class B:public A
{
public:
void ss()
{cout<<"world"<<endl;}
};
int main()
{
B b1;
b1.ss(); //調用的是類B中新增的ss()函數
b1.A::ss(); //調用的是類A中的ss()函數
}
虛函數真正作用:突破了無法通過基類指針或引用去調用派生類對象中的成員函數的限制,從而實現了動態多態性。
舉例分析:
class A
{
public:
virtual void ss()
{cout<<"hello"<<endl;}
};
class B:public A
{
public:
void ss()
{cout<<"world"<<endl;}
};
class C:public B
{
public:
void ss()
{cout<<"!!"<<endl;}
};
void show(A *p)
{
p->ss();
}
int main()
{
A a1;
B b1;
C c1;
show(&a1);
show(&b1);
show(&c1);
}