<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # C++ 虛函數 > 原文: [https://www.programiz.com/cpp-programming/virtual-functions](https://www.programiz.com/cpp-programming/virtual-functions) #### 在本文中,您將了解虛擬函數及其使用位置。 另外,您還將學習純虛函數和抽象類。 虛函數是您希望在派生類中重新定義的基類中的成員函數。 在詳細介紹之前,讓我們先了解一下為什么首先需要虛擬函數。 * * * ## 一個例子 讓我們假設,我們正在開發一個游戲(特別是武器)。 我們創建了`Weapon`類,并派生了兩個類`Bomb`和`Gun`以加載相應武器的特性。 ```cpp #include <iostream> using namespace std; class Weapon { public: void loadFeatures() { cout << "Loading weapon features.\n"; } }; class Bomb : public Weapon { public: void loadFeatures() { cout << "Loading bomb features.\n"; } }; class Gun : public Weapon { public: void loadFeatures() { cout << "Loading gun features.\n"; } }; int main() { Weapon *w = new Weapon; Bomb *b = new Bomb; Gun *g = new Gun; w->loadFeatures(); b->loadFeatures(); g->loadFeatures(); return 0; } ``` **輸出** ```cpp Loading weapon features. Loading bomb features. Loading gun features. ``` 我們定義了`Weapon`,`Bomb`和`Gun`類的三個指針對象`w`,`b`和`g`。 并且,我們使用以下命令調用了每個對象的`loadFeatures()`成員函數: ```cpp w->loadFeatures(); b->loadFeatures(); g->loadFeatures(); ``` 完美的作品! 但是,我們的游戲項目開始變得越來越大。 并且,我們決定創建一個單獨的`Loader`類來加載武器特性。 此類`Loader`類根據選擇的武器來加載武器的其他函數。 ```cpp class Loader { public: void loadFeatures(Weapon *weapon) { weapon->features(); } }; ``` `loadFeatures()`加載特定武器的特性。 * * * ### 讓我們嘗試實現我們的`Loader`類 ```cpp #include <iostream> using namespace std; class Weapon { public: Weapon() { cout << "Loading weapon features.\n"; } void features() { cout << "Loading weapon features.\n"; } }; class Bomb : public Weapon { public: void features() { this->Weapon::features(); cout << "Loading bomb features.\n"; } }; class Gun : public Weapon { public: void features() { this->Weapon::features(); cout << "Loading gun features.\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; } ``` **輸出** ```cpp Loading weapon features. Loading weapon features. Loading weapon features. Loading weapon features. ``` 我們的實現似乎是正確的。 但是,武器特性被加載了 4 次。 為什么? 最初,武器對象`w`指向`Bomb`類的`b`對象。 并且,我們嘗試使用指向`Loader`類的指針的`l`對象將其傳遞給`loadFeatures()`函數來加載`Bomb`對象的特性。 同樣,我們嘗試加載`Gun`對象的特性。 但是,`Loader`類的`loadFeatures()`函數將指向`Weapon`類的對象的指針作為參數: ```cpp void loadFeatures(Weapon *weapon) ``` 這就是武器特性被加載 4 次的原因。 要解決此問題,我們需要使用`virtual`關鍵字使基類(`Weapon`類)的特性虛擬化。 ```cpp class Weapon { public: virtual void features() { cout << "Loading weapon features.\n"; } }; ``` * * * ## 示例:使用虛函數解決問題 ```cpp #include <iostream> using namespace std; class Weapon { public: virtual void features() { cout << "Loading weapon features.\n"; } }; class Bomb : public Weapon { public: void features() { this->Weapon::features(); cout << "Loading bomb features.\n"; } }; class Gun : public Weapon { public: void features() { this->Weapon::features(); cout << "Loading gun features.\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; } ``` **輸出** ```cpp Loading weapon features. Loading bomb features. Loading weapon features. Loading gun features. ``` 另外,請注意,`l->loadFeatures(w)`函數根據`l`對象所指向的對象調用不同類的函數。 使用虛函數使我們的代碼不僅更清晰,而且更加靈活。 在以上程序中,武器特性被打印了兩次。 我們建議您在上述程序上添加其他代碼,以僅加載一次武器特性。 如果我們想添加另一種武器(比如說刀),我們可以輕松地添加和加載其特性。 **怎么樣**? ```cpp class Knife : public Weapon { public: void features() { this-<Weapon::features(); cout >> "Loading knife features.\n"; } }; ``` 并且,在`main()`函數中。 ```cpp Knife k; w = &k; l->loadFeatures(w); ``` 值得注意的是,我們沒有更改`Loader`類中的任何內容來加載刀的特征。 * * * ## C++ 抽象類和純虛函數 面向對象編程的目的是將一個復雜的問題分成幾個小集合。 這有助于有效理解和處理問題。 有時,僅在更好地可視化問題的情況下才需要使用繼承。 在 C++ 中,您可以創建一個無法實例化的抽象類(您不能創建該類的對象)。 但是,您可以從中派生一個類并實例化派生類的對象。 抽象類是無法實例化的基類。 包含純虛函數的類稱為抽象類。 * * * ## 純虛函數 聲明以`= 0`結尾的虛函數稱為純虛函數。 例如, ```cpp class Weapon { public: virtual void features() = 0; }; ``` 在這里,純虛函數是 ```cpp virtual void features() = 0 ``` 并且,類`Weapon`是抽象類。 * * * ## 示例:抽象類和純虛函數 ```cpp #include <iostream> using namespace std; // Abstract class class Shape { protected: float l; public: void getData() { cin >> l; } // virtual Function 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 << "Enter length to calculate the area of a square: "; s.getData(); cout<<"Area of square: " << s.calculateArea(); cout<<"\nEnter radius to calculate the area of a circle: "; c.getData(); cout << "Area of circle: " << c.calculateArea(); return 0; } ``` **輸出** ```cpp Enter length to calculate the area of a square: 4 Area of square: 16 Enter radius to calculate the area of a circle: 5 Area of circle: 78.5 ``` 在此程序中,在`Shape`類中定義了純虛函數`virtual float area() = 0;`。 需要注意的一件事是,您應該在派生類中覆蓋基類的純虛函數。 如果覆蓋失敗,則派生類也將成為抽象類。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看