0

全て:

C++ でポリモーフィズムを研究していると、ここに小さな例が見つかります。

#include <iostream>
using namespace std;
class Base{
public:
virtual void f(float x){cout<<"Base::f(float)"<<x<<endl;}
        void g(float x){cout<<"Base::g(float)"<<x<<endl;}
        void h(float x){cout<<"Base::h(float)"<<x<<endl;}
};

class Derived:public Base{
public:
virtual void f(float x){cout<<"Derived::f(float)"<<x<<endl;}
        void g(int x){cout<<"Derived::g(int)"<<x<<endl;}
        void h(float x){cout<<"Derived::h(float)"<<x<<endl;}
};
int main(void){
  Derived d;
  Base *pb=&d;
  Derived *pd=&d;

  //Good:behavior depends solely on type of the object
  pb->f(3.14f);     //Derived::f(float)3.14
  pd->f(3.14f);     //Derived::f(float)3.14

  //Bad:behavior depends on type of the pointer
  pb->g(3.14f);     //Base::g(float)3.14
  pd->g(3.14f);     //Derived::g(int)3(surprise!)

  //Bad:behavior depends on type of the pointer
  pb->h(3.14f);     //Base::h(float)3.14(surprise!)
  pd->h(3.14f);     //Derived::h(float)3.14


  return 0;
}

仮想関数を研究した後、ポリモーフがどのように機能するかを理解したと思いますが、このコードにはまだいくつかの疑問があります。このコードがどのように機能するかを誰かに説明してほしくありません。クラス(詳細は必要ありません。Vtableに配置されたメソッド関数ポインター(またはインデックス)とそれらの構造が仮想継承されたものではないことを示すだけです)。

pb->h(3.14f) から; //Base::h(float)3.14(驚き!) 複数の vtable が必要だと思いますが、そうですか?

ありがとう!

4

1 に答える 1

2

あなたのコードには、ポリモーフィック ( virtual) メンバー関数のシグネチャが 1 つしかありません: f(float). 他の 3 つの関数 、g(float)g(int)およびh(float)は仮想関数ではありません。あなたの「(サプライズ!)」コメントはg()andh()の呼び出しの後であるため、これらの関数がポリモーフィックではないことに驚いているか、非ポリモーフィック関数の動作に実際に驚いていると思います。

ポリモーフィックでないことg()に驚いた場合は、 がポリモーフィック関数の前に配置されていることに注意してください。関数が宣言されていない場合、それが基本クラスの仮想関数と同じシグネチャを持っている場合にのみポリモーフィックになります (これはinが冗長であることも意味しますが、個人的にはそのような冗長な使用は良いスタイルだと感じています) . の前にしか現れないので、 だけがポリモーフィックになります。h()virtualvirtualvirtualDerivedvirtualvirtualf(float)f(float)

h()はポリモーフィックではないため、ベース ポインターを介して呼び出すと のベース バージョンが呼び出されることは驚くことではありませh()h()

に関しては、派生クラスの名前は、宣言g()によって戻されない限り、基本クラスの対応する名前を隠します。これが、より良い一致である にもかかわらず、呼び出しが行わusingれる理由です。見えません。Derived クラスに入れると、float バージョンの が呼び出されます。(とは異なる関数シグネチャであるため、ここでは違いがないことに注意してください。一方が他方をオーバーライドする方法はありません。)pd->g(3.14f)Derived::g(int)Base::g(float)Base::gusing Base::g;g()virtualg()g(int)g(float)

HTH

于 2013-04-26T19:22:27.480 に答える