派生クラス オブジェクトを指す基本クラス ポインターを使用して仮想関数を呼び出す場合、コンパイラは動的バインディングを使用して派生バージョンを呼び出すことを知っています。しかし、基本クラス オブジェクトを指す基本クラス ポインターを使用して仮想関数を呼び出す場合、コンパイラは動的バインディングまたは静的バインディングを使用して仮想関数を呼び出しますか?
例えば:
class Base
{
public:
virtual void show()
{
cout << "base class";
}
}
int main()
{
Base *pb; //Base class pointer
Base b; //Base class object
pb = &b;
pb->show(); //Is static binding or dynamic binding?
}
私の英語はとても下手なので、質問はできるだけ簡単にしたいのですが、以下に詳しく説明します。
実際の問題は、動的バインディングをトリガーする方法を要約していることに起因します。最初に、トリガー条件を要約します。
- 関数は仮想関数でなければなりません。
- 関数を呼び出すには、ポインターまたは参照を使用する必要があります。
2 つのトリガー条件は、「基本クラスのポインターが基本クラスのオブジェクトを指している場合、コンパイラーは動的バインディングを使用するかどうか」という問題を引き起こします。
私は検索回答のグーグルを持っていて、フラグメントを見つけました(デモはこちらです):
struct A {
virtual void f() { cout << "Class A" << endl; }
};
struct B: A {
//Note that it not overrides A::f.
void f(int) { cout << "Class B" << endl; }
};
struct C: B {
void f() { cout << "Class C" << endl; }
};
int main() {
B b; C c;
A* pa1 = &b;
A* pa2 = &c;
// b.f();
pa1->f();
pa2->f();
}
上記の例の出力は次のとおりです。
"Class A"
"Class C"
pa1->f()
will outputに従ってClass A
、3 番目のトリガー条件を要約します。
3.基本クラスの関数は、派生クラスでオーバーライドする必要があります。
3 つのトリガー条件に従って、基本クラス オブジェクトを指す基本クラス ポインターを使用して仮想関数を呼び出す場合、仮想関数はオーバーライドされないため、コンパイラは静的バインディングを使用して仮想関数を呼び出します。
ただし、派生クラス オブジェクトを指す派生クラス ポインターを使用して仮想関数を呼び出す場合、仮想関数がオーバーライドされるため、動的バインディングが使用されます。
とても混乱しました。