2

ポインターなしで仮想関数を使用するとどうなりますか? 例えば:

#include <iostream>
using namespace std;
class Parent
{
 public:
   Parent(int i) { }
   virtual void f() { cout<<"Parent"<<endl; }
};

class Child : public Parent
{
 public:
   Child(int i) : Parent(i) { }
   virtual void f() { Parent::f(); cout<<" Child"<<endl; }
};

int main()
{
    Parent a(2);
    Parent b = Child(2);
    a.f();
    b.f();
    return 0;
}

^^なぜうまくいかないのですか?仮想メソッドが実際にどのように機能するかについては、どこで確認できますか?

4

3 に答える 3

14

この効果は「スライス」と呼ばれます。

Parent b = Child(2); // initializes a new Parent object using part of Child obj

C++ では、動的型は、参照またはポインターの静的型とのみ異なる場合があります。直接オブジェクトがあります。つまり、あなたの疑いは本質的に正しかったのです。

于 2010-08-30T10:58:53.440 に答える
4

次のことを試してください。

std::auto_ptr<Parent> b = new Child(2);

Childコードでは、オブジェクトの一部を にコピーしますb。これはいわゆるオブジェクトのスライスです。

于 2010-08-30T10:59:19.697 に答える
1

仮想関数メカニズムは、仮想関数が適切な参照または適切なポインターを介して呼び出された場合にのみ有効になります。コンストラクタ/デストラクタまたは :: 演算子の使用中は、仮想関数呼び出しメカニズムが抑制されることに注意してください。

以下のコードの場合、仮想関数メカニズムが有効になります。

Child c;
Parent &a = c;
a.f();

ポインターがない場合、仮想関数呼び出しであっても、呼び出しは静的にバインドされます。

編集2:

$10.3/6 - [注: 仮想関数の呼び出しの解釈は、それが呼び出されるオブジェクトの型 (動的型) に依存しますが、非仮想メンバー関数の呼び出しの解釈は型のみに依存します。そのオブジェクトを示すポインターまたは参照の (静的型) (5.2.2)。]

于 2010-08-30T10:58:41.147 に答える