なぜこの方法が私が期待していたように仮想を呼び出さないのですか?
-
02-10-2019 - |
質問
ポインターなしで仮想関数を使用したときに何が起こるかを聞きたいですか?例えば:
#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;
}
^^なぜそれが機能しないのですか?仮想メソッドが実際にどのように機能するかについて、どこで何かを見つけることができますか?
解決
この効果は「スライス」と呼ばれます。
Parent b = Child(2); // initializes a new Parent object using part of Child obj
C ++では、動的タイプは参照またはポインターの静的タイプとのみ異なる場合があります。直接オブジェクトがあります。したがって、あなたの疑いは本質的に正しかった。
他のヒント
以下を試してください:
std::auto_ptr<Parent> b = new Child(2);
あなたのコードであなたはの部分をコピーします Child
オブジェクト b
. 。これはそう呼ばれています オブジェクトスライシング.
仮想関数メカニズムは、適切な参照または適切なポインターのいずれかを介して仮想関数が呼び出される場合にのみ有効になります。仮想関数呼び出しメカニズムは、コンストラクター/デストラクタで、または::演算子を使用しているときに抑制されていることに注意してください。
コードが以下に示すように、仮想関数メカニズムが有効になります。
Child c;
Parent &a = c;
a.f();
ポインターがなければ、仮想関数呼び出しであっても、コールは静的にバインドされています。
編集2:
$ 10.3/6- [注:仮想関数の呼び出しの解釈は、それが呼ばれるオブジェクトのタイプ(動的タイプ)に依存しますが、非仮想メンバー関数の呼び出しの解釈はタイプにのみ依存しますそのオブジェクト(静的タイプ)(5.2.2)を示すポインターまたは参照の。
所属していません StackOverflow