3

これは非常に不自然で申し訳ありませんが、宿題の問題に関連しています。私がコメントした行を除いて、なぜすべてが起こるのか理解しています。なぜC++が何をしているのか説明してもらえますか?

ありがとう

#include <iostream>

using namespace std;

class X0 {};
class X1: public X0 {};
class X2: public X1 {};

class Y1
{
public:
    virtual void f(int v)       { cout << "Y1(int)" << endl; }
    virtual void f(const X0 *x) { cout << "Y1(X0)" << endl; }
    virtual void f(const X1 *x) { cout << "Y1(X1)" << endl; }
};

class Y2: public Y1
{
public:
    virtual void f(const X0 *x) { cout << "Y2(X0)" << endl; }
    virtual void f(const X1 *x) { cout << "Y2(X1)" << endl; }
    virtual void f(const X2 *x) { cout << "Y2(X2)" << endl; }
};

int main(int argc, char * argv[])
{
    X2 x2; X2 *X2Pointer = &x2;
    Y2 y2; Y1 *Y1Pointer = &y2;

    cout << "What is about to happen?" << endl;
    //Y1 pointer points to a Y2 object.
    //The Y2 class, upon being given an X2 pointer, should print Y2(X2)
    Y1Pointer->f(X2Pointer);
    cout << "Why did I just print Y2(X1)" << endl;
    return 0;
}
4

4 に答える 4

3

このクラスY1は、次のオーバーロードを公開しますf()

class Y1: public Y0 {
public:
    virtual void f(int v)       { cout << "Y1(int)" << endl; }
    virtual void f(const X0 *x) { cout << "Y1(X0)" << endl; }
    virtual void f(const X1 *x) { cout << "Y1(X1)" << endl; }
    // ...
};

f()継承元と呼ばれる他のすべてのメソッドY0は非表示になります。つまり、あなたが呼び出すとき

Y1Pointer->f(X2Pointer);

コンパイラは の 3 つのオーバーロードでオーバーロード解決を行い、最適な一致でf()あるという結論に達し、f(const X1*)この関数を呼び出します。結局のところ、これはvirtualによってオーバーライドされる関数でY2あり、したがって、 を呼び出しますY2::f(const X1*)

于 2012-11-11T15:00:43.173 に答える
1

オーバーロードの解決は、関連する静的型に基づいて決定されます。

Y1Pointer->f(X2Pointer)Y1::f(const X1 *x)の静的型は であるため、Y1PointerY1*に一致し、パラメーターを使用したY1::f(const X1 *x)への呼び出しに最適です。fX2*

Y1::f(const X1 *x)は仮想であるため、呼び出される実際の関数は動的型によって決定されます。Y1Pointerは を指しているY2ため、 のY2バージョンf(const X1 *x)が呼び出されます。

于 2012-11-11T15:04:12.703 に答える
1

クラスY1には、を消費するオーバーロードはありませんX2 *。関数呼び出しに最適なのY1Pointer->f(X2Pointer)Y1::f(X1 const *). どのオーバーロードが選択されているかは関係ないため、Y1Pointerポイントがより派生している実際のオブジェクトは問題ではありません。Y1

于 2012-11-11T15:05:09.107 に答える
0

他の人が述べたように、問題は関数の隠蔽です。しかし、あなたができることはusing Y0::f;、あなたが望む結果を得るためにY1行の中に書くことです.

于 2012-11-11T15:13:13.657 に答える