C++ 基礎(chǔ)教程

C++ 流程控制

C++ 函數(shù)

C++ 數(shù)組 & 字符串

C++ 數(shù)據(jù)結(jié)構(gòu)

C++ 類 & 對象

C++ 指針

C++ 繼承

C++ STL 教程

C++ 參考手冊

C++ 虛函數(shù)和抽象類

在本文中,您將了解虛函數(shù)及其使用位置。此外,您還將學(xué)習(xí)純虛函數(shù)和抽象類。

虛函數(shù)是基類中的成員函數(shù),您希望在派生類中重新定義這些函數(shù)。

在詳細(xì)介紹之前,讓我們先了解一下為什么首先需要虛函數(shù)。

一個實例開始

讓我們假設(shè),我們正在開發(fā)一個游戲(比如道具:武器)。

我們創(chuàng)建了Weapon該類并派生了兩個類,Bomb和Gun加載了各自武器的功能。

#include <iostream>
using namespace std;

class Weapon {
   public:
   void loadFeatures() { cout << "載入武器特性。\n"; }
};

class Bomb : public Weapon {
   public:
   void loadFeatures() { cout << "裝載刀的特性。\n"; }
};

class Gun : public Weapon {
   public:
   void loadFeatures() { cout << "裝載槍的特性\n"; }
};

int main() {
   Weapon *w = new Weapon;
   Bomb *b = new Bomb;
   Gun *g = new Gun;

   w->loadFeatures();
   b->loadFeatures();
   g->loadFeatures();

   return 0;
}

輸出結(jié)果

裝載武器特性。
裝載刀的特性。
裝載槍的特性。

我們分別定義了Weapon,Bomb和Gun類的三個指針對象w,b和g。 并且,我們使用以下命令調(diào)用每個對象的loadFeatures()成員函數(shù):

w->loadFeatures();
b->loadFeatures();
g->loadFeatures();

完美的作品!

但是,我們的游戲項目開始變得越來越大。并且,我們決定創(chuàng)建一個單獨的Loader類來加載武器功能。

此類Loader根據(jù)選擇的武器加載武器的其他功能。

class Loader
{
   public:
     void loadFeatures(Weapon *weapon)
     {
        weapon->features();
     }     
};

loadFeatures()負(fù)載特定武器的特征。

讓我們嘗試實現(xiàn)我們的Loader類

#include <iostream>
using namespace std;
class Weapon {
   public:
   Weapon() { cout << "裝載武器特性。\n"; }

   void features() { cout << "裝載武器特性。\n"; }
};
class Bomb : public Weapon {
   public:
   void features() {
      this->Weapon::features();
      cout << "裝載刀的特性。\n";
   }
};
class Gun : public Weapon {
   public:
   void features() {
      this->Weapon::features();
      cout << "加載槍的特性。\n";
   }
};
class Loader {
   public:
   void loadFeatures(Weapon *weapon) {
      weapon->features();
   }
};
int main() {
   Loader *l = new Loader;
   Weapon *w;
   Bomb b;
   Gun g;
   w = &b;
   l->loadFeatures(w);
   w = &g;
   l->loadFeatures(w);
   return 0;
}

輸出結(jié)果

裝載武器特性。
裝載武器特性。
裝載武器特性。
裝載武器特性。

我們的實現(xiàn)似乎是正確的。但是,裝載武器特性被加載了4次。為什么?

最初,武器對象w指向(Bomb)類的b對象。 并且,我們嘗試使用l對象指向(Loader類的)指針將其傳遞給loadFeatures()函數(shù)來加載Bomb對象的特性。

同樣,我們嘗試加載Gun對象的特性。

但是,Loader類的loadFeatures()函數(shù)將指向Weapon類對象的指針作為參數(shù):

void loadFeatures(Weapon *weapon)

這就是為什么武器特性被加載4次的原因。為了解決這個問題,我們需要使用virtual關(guān)鍵字實現(xiàn)基類(Weapon類)的虛函數(shù)。

class Weapon
{
    public:
      virtual void features()
         { cout << "裝載武器特性。\n"; }
};

示例:使用虛函數(shù)解決問題

#include <iostream>
using namespace std;

class Weapon {
   public:
   virtual void features() { cout << "裝載武器特性。\n"; }
};

class Bomb : public Weapon {
   public:
   void features() {
      this->Weapon::features();
      cout << "裝載刀的特性。\n";
   }
};

class Gun : public Weapon {
   public:
   void features() {
      this->Weapon::features();
      cout << "加載槍的特性。\n";
   }
};

class Loader {
   public:
   void loadFeatures(Weapon *weapon) {
      weapon->features();
   }
};

int main() {
   Loader *l = new Loader;
   Weapon *w;
   Bomb b;
   Gun g;

   w = &b;
   l->loadFeatures(w);

   w = &g;
   l->loadFeatures(w);

   return 0;
}

輸出結(jié)果

裝載武器特性。
裝載刀的特性。
裝載武器特性。
加載槍的特性。

另外,注意,l->loadFeatures(w)函數(shù)會根據(jù)l對象所指向的對象調(diào)用不同類的函數(shù)。

使用虛函數(shù)使我們的代碼不僅更加清晰,而且更加靈活。

在以上程序中,“裝載武器特性?!北淮蛴×藘纱巍N覀兘ㄗh您在上述程序上添加其他代碼,以便只加載一次武器特性。

如果我們想添加另一種武器(比如說 弓),我們可以輕松地添加和加載其特性。如何添加?

class Bow : public Weapon {
   public:
   void features() {
      this-<Weapon::features();
      cout >> "加載弓的特性。\n";
   }
};

并且,在main()函數(shù)中添加如下代碼。

Bow b; 
w = &b; 
l->loadFeatures(w);

值得注意的是,我們沒有更改Loader類中的任何內(nèi)容來加載刀的特性。

C ++抽象類和純虛函數(shù)

面向?qū)ο缶幊痰哪康氖菍⒁粋€復(fù)雜的問題分成幾個小集合。這有助于有效理解和處理問題。

有時,最好僅在更好地可視化問題的情況下使用繼承。

在C ++中,您可以創(chuàng)建一個無法實例化的抽象類(您不能創(chuàng)建該類的對象)。但是,您可以從中派生一個類并實例化派生類的對象。

抽象類是無法實例化的基類。

包含純虛函數(shù)的類稱為抽象類。

純虛函數(shù)

聲明以結(jié)尾的=0虛函數(shù)稱為純虛函數(shù)。例如,

class Weapon
{
    public:
      virtual void features() = 0;
};

在這里,純虛函數(shù)是

virtual void features() = 0

并且,該類Weapon是抽象類。

示例:抽象類和純虛函數(shù)

#include <iostream>
using namespace std;

// 抽象類(不允許實例化的類)
class Shape                   
{
    protected:
       float l;
    public:
       void getData()       
       {
           cin >> l;
       }
       
       // 虛函數(shù)
       virtual float calculateArea() = 0;
};

class Square : public Shape
{
    public:
       float calculateArea()
       {   return l*l;  }
};

class Circle : public Shape
{
    public:
       float calculateArea()
       { return 3.14*l*l; }
};

int main()
{
    Square s;
    Circle c;

    cout << "輸入長度來計算正方形的面積: ";
    s.getData();
    cout<<"正方形的面積: " << s.calculateArea();
    cout<<"\n輸入半徑以計算圓的面積: ";
    c.getData();
    cout << "圓的面積: " << c.calculateArea();

    return 0;
}

輸出結(jié)果

輸入長度來計算正方形的面積: 4
正方形的面積: 16
輸入半徑以計算圓的面積: 5
圓的面積: 78.5

在此程序中,純虛函數(shù)virtual float area()= 0; 在Shape類中定義。

需要注意的一件事是,您應(yīng)該在派生類中重寫基類的純虛函數(shù)。 如果重寫失敗,則派生類也將成為抽象類。

丰满人妻一级特黄a大片,午夜无码免费福利一级,欧美亚洲精品在线,国产婷婷成人久久Av免费高清