多態(tài)

2018-08-12 22:03 更新

多態(tài)

多態(tài)性意味著有多種形式。通常,多態(tài)發(fā)生在類之間存在層級關(guān)系且這些類有繼承關(guān)系的時候。

C++ 多態(tài)性是指不同的對象發(fā)送同一個消息,不同對象對應同一消息產(chǎn)生不同行為。

考慮下面的例子,一個基類派生了其他的兩類:

    #include <iostream> 
    using namespace std;

    class Shape {
       protected:
      int width, height;
       public:
      Shape( int a=0, int b=0)
      {
     width = a;
     height = b;
      }
      int area()
      {
     cout << "Parent class area :" <<endl;
     return 0;
      }
    };
    class Rectangle: public Shape{
       public:
      Rectangle( int a=0, int b=0):Shape(a, b) { }
      int area ()
      { 
     cout << "Rectangle class area :" <<endl;
     return (width * height); 
      }
    };
    class Triangle: public Shape{
       public:
      Triangle( int a=0, int b=0):Shape(a, b) { }
      int area ()
      { 
     cout << "Triangle class area :" <<endl;
     return (width * height / 2); 
      }
    };
    // Main function for the program
    int main( )
    {
       Shape *shape;
       Rectangle rec(10,7);
       Triangle  tri(10,5);

       // store the address of Rectangle
       shape = &rec;
       // call rectangle area.
       shape->area();

       // store the address of Triangle
       shape = &tri;
       // call triangle area.
       shape->area();

       return 0;
    }

上面的代碼編譯和執(zhí)行時,它產(chǎn)生以下結(jié)果:

    Parent class area
    Parent class area

輸出結(jié)果不正確的原因是對函數(shù) area() 的調(diào)用被編譯器設置了一次,即在基類中定義的版本,這被稱為對函數(shù)調(diào)用的靜態(tài)分辨或者靜態(tài)鏈接,靜態(tài)鏈接就是在程序被執(zhí)行之前函數(shù)調(diào)用是確定的。這有時也被稱為早期綁定,因為函數(shù) area() 在編譯程序期間是固定的。

但是現(xiàn)在,讓我們對程序做略微修改,并在 Shape 類中 area() 的聲明之前加關(guān)鍵字 virtual ,它看起來像這樣:

    class Shape {
       protected:
      int width, height;
       public:
      Shape( int a=0, int b=0)
      {
     width = a;
     height = b;
      }
      virtual int area()
      {
     cout << "Parent class area :" <<endl;
     return 0;
      }
    };

這輕微的修改后,前面的示例代碼編譯和執(zhí)行時,它會產(chǎn)生以下結(jié)果:

    Rectangle class area
    Triangle class area

這一次,編譯器關(guān)注的是指針的內(nèi)容而不是它的類型。因此,由于三角形和矩形類對象的地址被存儲在形狀類中,各自的 area() 函數(shù)可以被調(diào)用。

正如你所看到的,每個子類都有一個對 area() 函數(shù)的實現(xiàn)。通常多態(tài)就是這樣使用的。你有不同的類,它們都有一個的相同名字的函數(shù),甚至有相同的參數(shù),但是對這個函數(shù)有不同的實現(xiàn)。

虛函數(shù)

基類中的虛函數(shù)是一個使用關(guān)鍵字 virtual 聲明的函數(shù)。派生類中已經(jīng)對函數(shù)進行定義的情況下,定義一個基類的虛函數(shù),就是要告訴編譯器我們不想對這個函數(shù)進行靜態(tài)鏈接。

我們所希望的是根據(jù)調(diào)用函數(shù)的對象的類型對程序中在任何給定指針中被調(diào)用的函數(shù)的選擇。這種操作被稱為動態(tài)鏈接,或者后期綁定。

純虛函數(shù)

可能你想把虛函數(shù)包括在基類中,以便它可以在派生類中根據(jù)該類的對象對函數(shù)進行重新定義,但在許多情況下,在基類中不能對虛函數(shù)給出有意義的實現(xiàn)。

我們可以改變基類中的虛函數(shù) area() 如下:

    class Shape {
       protected:
      int width, height;
       public:
      Shape( int a=0, int b=0)
      {
     width = a;
     height = b;
      }
      // pure virtual function
      virtual int area() = 0;
    };

area() = 0 就是告訴編譯器上面的函數(shù)沒有函數(shù)體。上面的虛函數(shù)就被稱為純虛函數(shù)。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號