1. 程式人生 > >C++ 多態性和虛函數

C++ 多態性和虛函數

urn 是否 end 能夠 不能 一個 image 使用 tro

2017-06-27 19:17:52

C++面向對象編程的一個重要的特性就是多態性,而多態性的實現需要依賴虛函數的幫助。

一、多態的作用:

  1. 隱藏實現細節,使得代碼能夠模塊化;
  2. 接口重用,實現“一個接口,多種方法”;

二、虛函數的聲明:

class Base

{

  virtual 返回值類型 函數名(形參表){}

}

  • 當基類的某個成員函數被聲明為虛函數後,其子類中的函數如果返回值類型,函數名,形參表一致的話,不論是否加了virtual關鍵字,都會被認為是虛函數。反之,則是同名隱藏。
  • virtual關鍵字只是在類中聲明的時候必須加上,在類外定義的時候不需要加virtual關鍵字
  • 構造函數,靜態成員函數不能是虛函數,析構函數可以是虛函數
    ,甚至鼓勵將析構函數寫成虛函數
  • 只有通過基類的對象指針,基類的對象引用來調用派生類的虛函數,才能體現虛函數的特性。單純通過子類來調用虛函數是無法體現這種動態聯編的特性的。

                                A* p=&b

                                A& p=b

三、多態性的實現

可以使用基類的對象指針來先後指向同一類族中的不同類對象,以便使用相同的調用方法去調用不同派生類的同名虛函數。

class A
{
    int a;
public:
    A(int x)
    {
        a=x;
    }

    
virtual void get(){cout<<"A::"<<a<<endl;} }; class B:public A { int b; public: B(int x,int y):A(x) { b=y; } void get(){cout<<"B::"<<b<<endl;} }; class C:public B { int c; public: C(int x,int y,int z):B(x,y) { c=z; }
void get(){cout<<"C::"<<c<<endl;} }; int main() { C c1(1,2,3); A* p1=&c1; B* p2=&c1; p1->get(); p2->get(); return 0; }

技術分享

四、純虛函數

定義一個基類的時候如果還無法給出虛函數的具體實現方式,可以將之聲明為純虛函數,純虛函數的實現完全依賴於各個派生類。

純虛函數的聲明:

virtual 返回值類型 函數名(形參表)=0;

  • 因為無法給出純虛函數的定義所以沒有函數體,沒有函數體和函數體為空是兩個概念,要加以區分;
  • 函數名賦值為0,本質上是將指向該函數的指針的地址賦值為0。在派生類沒有重定義之前是無法加以使用的。

五、抽象類

抽象類是指無法定義對象只能作為基類的一種特殊的類,但是可以定義對象指針,目的是為了實現多態性。

抽象類有兩種:

  1. 有純虛函數的基類
  2. 構造函數或者析構函數被定義為protected訪問

C++ 多態性和虛函數