10

私はこのコードを試しました:

struct FaceOfPast
{
    virtual void Smile() = 0;
};

struct FaceOfFuture
{
    virtual void Smile() = 0;
};

struct Janus : public FaceOfPast, public FaceOfFuture
{
    virtual void Smile() {printf(":) ");}
};

..。

void main()
{
    Janus* j = new Janus();
    FaceOfFuture* future = j;
    FaceOfPast* past = j;

    future->Smile();
    past->Smile();

    delete j;
}

意図したとおりに機能します(2つのスマイリーフェイスを出力します)が、あいまいSmile()であることを再宣言してコンパイルする必要はないと思います。Janus

それはどのように(そしてなぜ)機能しますか?

4

3 に答える 3

7

Smile()へのポインターを呼び出して、FaceOfFuture1FaceOfPastつのメソッドのみを宣言するため、あいまいさはありませんSmile()

基本クラス ポインターでメソッドを呼び出してもあいまいになることはないため、子クラス ポインターでメソッドを直接呼び出す場合の状況を扱いましょう

Janus* j = new Janus();
j->Smile();

派生クラスは、オーバーライドするだけでなく、基本クラスの の宣言も隠しますSmile()。派生クラスでメソッドをオーバーライドしない場合にのみ、あいまいさがあります。

以下がコンパイルされます。

struct FaceOfPast
{
    virtual void Smile() {printf(":) ");}
};
struct FaceOfFuture
{
    virtual void Smile() {printf(":) ");}
};
struct Janus : public FaceOfPast, public FaceOfFuture
{
   virtual void Smile() {printf(":) ");}
};
int main()
{
   Janus* j = new Janus();
   j->Smile();
}

を呼び出しますがSmileJanus基本クラスの宣言は隠されています。

以下はしません:

struct FaceOfPast
{
    virtual void Smile() {printf(":) ");}
};

struct FaceOfFuture
{
    virtual void Smile() {printf(":) ");}
};

struct Janus : public FaceOfPast, public FaceOfFuture
{
};

int main()
{
   Janus* j = new Janus();
   j->Smile();
}

あいまいさのため。

于 2012-04-24T12:05:42.220 に答える
1

C++ 標準 (10.3.2) によると:

仮想メンバー関数 vf がクラスBaseおよびクラスDerivedで宣言され、 Baseから直接的または間接的に派生した場合、同じ名前、parameter-type-list、cv-qualification、および ref-qualifier を持つメンバー関数vf (またはBase::vfが宣言されている場合、Derived ::vf [...]はBase::vfをオーバーライドします。

多重継承に対する特別な処理はないように思われるため、おそらくここにも当てはまりますvoid Janus::Smile()。両方の基本クラス メソッドとまったく同じ名前とシグネチャを持っているという理由だけで、あいまいさなしに両方のメソッドをオーバーライドします。

于 2012-04-24T14:38:41.537 に答える
0
Janus* j = new Janus();
FaceOfFuture* future = j;
FaceOfPast* past = j;

コードのこのセクションは、基本クラスにキャストダウンします。したがって、次のことを行うと

future->Smile();
past->Smile();

これは実際にはFaceofPastとFaceOfFutureへのポインタです。

于 2012-04-24T12:48:31.180 に答える