101

Visual C++ 2010 で次のシナリオを想定してみましょう。

#include <iostream>
#include <conio.h>

using namespace std;

class Base
{
public:
    int b;
    void Display()
    {
        cout<<"Base: Non-virtual display."<<endl;
    };
    virtual void vDisplay()
    {
        cout<<"Base: Virtual display."<<endl;
    };
};

class Derived : public Base
{
public:
    int d;
    void Display()
    {
        cout<<"Derived: Non-virtual display."<<endl;
    };
    virtual void vDisplay()
    {
        cout<<"Derived: Virtual display."<<endl;
    };
};

int main()
{
    Base ba;
    Derived de;

    ba.Display();
    ba.vDisplay();
    de.Display();
    de.vDisplay();

    _getch();
    return 0;
};

理論的には、この小さなアプリケーションの出力は次のようになります。

  • ベース: 非仮想ディスプレイ。
  • ベース: 仮想ディスプレイ。
  • ベース: 非仮想ディスプレイ。
  • 派生: 仮想ディスプレイ。

Base クラスの Display メソッドは仮想メソッドではないため、Derived クラスはそれをオーバーライドできないはずです。右?

問題は、アプリケーションを実行すると、次のように出力されることです。

  • ベース: 非仮想ディスプレイ。
  • ベース: 仮想ディスプレイ。
  • 派生: 非仮想ディスプレイ。
  • 派生: 仮想ディスプレイ。

つまり、仮想メソッドの概念を理解していなかったか、Visual C++ で奇妙なことが起こったのです。

誰かが説明を手伝ってくれませんか?

4

3 に答える 3

149

ええ、あなたは少し誤解しています。

この場合、派生クラスの同じ名前のメソッドは親メソッドを隠します。そうでない場合、基本クラスの非仮想メソッドと同じ名前のメソッドを作成しようとすると、エラーがスローされるはずだと想像できます。それは許可されており、問題はありません。メソッドを直接呼び出すと、問題なく呼び出されます。

ただし、非仮想であるため、ポリモーフィズムを可能にする C++ メソッド ルックアップ メカニズムは使用されません。たとえば、派生クラスのインスタンスを作成し、基本クラスへのポインターを介して「Display」メソッドを呼び出した場合、基本のメソッドが呼び出されますが、「vDisplay」の場合は派生メソッドが呼び出されます。

たとえば、次の行を追加してみてください。

Base *b = &ba;
b->Display();
b->vDisplay();
b = &de;
b->Display();
b->vDisplay();

...そして、期待どおりの出力を観察します。

ベース: 非仮想ディスプレイ。
ベース: 仮想ディスプレイ。
ベース: 非仮想ディスプレイ。
派生: 仮想ディスプレイ。

于 2012-06-17T00:18:17.570 に答える
26

はい、あなたは少し誤解しています:

純粋仮想機能:

virtual void fun1()=0-> 派生クラスでオーバーライドする必要があります

仮想機能:

virtual void fun2()-> オーバーライド可能

通常の機能:

void fun3()-> オーバーライドしないでください

ランタイム ポリモーフィズムを実現するには、C++ で仮想関数をオーバーライドする必要があります

于 2016-11-17T17:32:55.690 に答える
7

静的バインディングと動的バインディングのコンテキストで見てみるのも良いと思います。

メソッドが非仮想の場合 (Java とは異なり、C++ では既定で既に存在します)、メソッドはコンパイル時に呼び出し元にバインドされ、実行時にポイントされる実際のオブジェクトを知ることは不可能です。したがって、重要なのは変数の型だけで、どれが「ベース」であるかです。

于 2017-11-03T14:02:12.580 に答える