天天看點

多态性,虛函數與純虛函數(複習幹貨)多态性,虛函數與純虛函數(複習幹貨)

多态性,虛函數與純虛函數(複習幹貨)

向對象發送同一個消息,不同的對象在接收時會産生不同的
   行為(即方法,屬于本對象的行為)。
           
  1. 多态分為靜态多态性和動态多态性。
  • 靜态多态性,函數重載和運算符重載都屬于靜态多态性。
  • 動态多态性,通過虛函數實作。
  1. 靜态多态性:編譯階段确定函數位址(位址早綁定)。

          函數調用速度快,效率高,但是缺乏靈活性。

     動态多态性:運作階段确定函數位址(位址晚綁定)。

利用虛函數實作動态多态性

  1. 所謂虛函數,就是在基類中聲明函數是虛拟的,并不是實際存在的函數,然後在派生類中才正式定義此函數。
  2. 虛函數實作的動态多态性就是:同一類族中不同類的對象,對同一函數調用作出不同的響應。
  3. 虛函數
  • 基類中聲明(virtual),在類外定義虛函數不必在函數名前加virtual,函數體可以是空,它的作用隻是定義了一個虛函數名,具體功能留給派生類去添加實作。
  • 在派生類中聲明時,virtual可以寫,也可以不寫,但習慣性一般在每一層聲明該函數時都加virtual,使程式更加清晰。
  • 在派生類中重新定義此虛函數,函數類型,函數名,函數參數個數及參數類型必須與基類的虛函數相同。
  1. 虛函數的作用是允許在派生類中重新定義與基類同名的函數,并且可以通過基類指針或引用來通路基類和派生類中的同名函數。   

    Base類.h檔案

#include<iostream>
    usaing namespace std;
    class Base
    {
        public:
            Base(int a,  int b){ this->a = a;  this->b = b;}
            virtual  void  display();
        private:
            int a;
            int b;
     };
           

基類.cpp檔案

#include"Base.h"

void Base::dispaly()
{
   cout<<"我是基類"<<endl;
   cout<<"a="<<a<<"\t"<<"b="<<b<<endl;
   // 可以是空
}
           

派生類.h檔案

#include"Base.h"
class  Son :
   public  Base
{
    public: 
        Son(int a, int b, int c):Base(a,b){this->c = c;}
        virtual void display();
    private:
        int c;
};
           

派生類 .cpp檔案

#include"Son.h"

void Son::display()
{
   cout<<"我是Son的虛函數"<<endl;
   cout<<"a = "<<a<<"\tb="<<b<<"\tc="<<c<<endl;
}
           

main函數

#include"Son.h"
int main()
{
   Son s(1,2,3);
   Base *p = s; 
   p->display();
   return 0;
}
           

運作結果:

我是Son的虛函數
  a=1	b=2   c=3
           

純虛函數

  1. 什麼是抽象類?

    凡是包含純虛函數的類都是抽象類。由于它常作為基類,通常稱為抽象基類。因為純虛函數是不能被調用的,包含純虛函數的類是無法建立對象的(可以建立基類的指針或引用),抽象類的作用是作為一個類族的共同基類,或者說,為一個類族提供一個公共接口。(頂部可以有好幾層都是抽象類)

  • 靜态成員函數不能定義為虛函數,也不能定義成純虛函數。
  1. 定義這些抽象類的唯一目的是用它作為基類去建立派生類。
  2. 什麼是具體類?

    在抽象類所派生的新類中對基類的所有純虛函數進行定義,那麼這些函數就被賦予了功能,可以被調用,這個派生類就不是抽象類,而是可以定義對象的具體類。

  • 如果在派生類中沒有對所有純虛函數進行定義,則此派生類仍然是抽象類,不能定義對象。
  • 當派生類成為具體類後,就可以用基類指針指向派生類對象,用指針調用虛函數,實作多态。
  1. 派生類對基類的純虛函數進行定義後,該函數就成為了虛函數,而不是純虛函數。
  2. 純虛函數聲明: virtual 函數類型 函數名 (參數清單) = 0;

    隻需要聲明,不需要在基類具體實作。

    聲明如下:

virtual   void   display() =  0;
           
  • 派生類中必須與基類擁有相同的函數類型,函數名,參數個數以及參數類型。

基類 .h檔案

#include<iostream>
using namespace std;

class Shape
{
public:
	virtual double area() = 0;
	virtual void display() = 0;
};
           

派生類 .h檔案

#include "Shape.h"
class Triangle :
    public Shape
{
    //三角形
public:
    Triangle(int side, int high) { this->side = side; this->high = high; }
    virtual double area();
    virtual void display();
private:
    int side;
    int high;
};
           

派生類 .cpp檔案

#include "Triangle.h"

double Triangle::area()
{
	return (double)side * high * (1.0/2);
}

void Triangle::display()
{
	all_area += area();
	cout << "Triangle的面積是:" << area() << endl;
}
           

main函數

#include"Triangle.h"

int main()
{   Triangle e(2, 4);
    Shape* pt;
    pt = &e;
    pt->display();
           

運作結果:

Triangle的面積是:4
           

繼續閱讀