5

このインターフェースがあると仮定します:

class A{  
 public:  
  virtual foo()=0;  
};

Bそして、このインターフェースを実装するクラス:

class B:public A{    
 public:   
  virtual foo(){} //Foo implemented by B   
}

最後に、クラスCを持ちAB基本クラスとしてのクラス:

Class C : public A, public B {
};

私の質問は、 ?への明示的な呼び出しを行わずに、の実装fooがクラスからのものであることをコンパイラに伝える方法があるということです。BB::foo()

4

3 に答える 3

3

@BenVoigtがコメントで指摘しているように、以下の回答はg ++のバグが原因でのみ機能します(つまり、機能し続けることが保証されておらず、移植性がないことは間違いありません)。したがって、特定の(バギー)コンパイラを使用する場合は、必要なことを実行できますが、使用する必要のあるオプションではありません。

ただし、仮想継承を使用してください


これは、質問のコードが暗示しているシナリオではありませんが、文

私の質問は、B :: foo()を明示的に呼び出さなくても、fooの実装がクラスBの実装であることをコンパイラに伝える方法があるということです。

::修飾子を使用せずに、関数の複数の基本バージョンを区別するための構文を求めているようです。

usingこれは、ディレクティブを使用して行うことができます。

#include <iostream>
class A {
public:
A(){}
virtual void foo(){std::cout<<"A func";}
};

class B: virtual public A {
  public:
  B(){}
  virtual void foo(){std::cout<<"B func";}
};
class C:virtual public A, virtual public B {
    public:
    C(){}
    using A::foo; // tells the compiler which version to use
                   // could also say using B::foo, though this is unnecessary
};

int main() {
    C c;
    c.foo(); // prints "A func"
    return 0;
}

もちろん、他の回答が指摘しているように、質問のコード自体はこれをまったく必要としません。

于 2012-12-26T18:20:25.593 に答える
2

仮想継承を使用するだけで、Aによって提供されるサブオブジェクトBはで使用されるオブジェクトと同じになりますC

または、書き込み...とにかく、基本クラスを介してclass C : public B暗黙的に使用できます。AB


質問が編集される前:

B::fooとは互換性がありませんA::foo

必要な署名は

ReturnType /* missing from question */ foo(A* const this /* this parameter is implicit */);

しかしB::foo、署名があります

ReturnType foo(B* const this);

A*仮想関数に渡される、は、実装に必要なではありませんB*Bから継承された場合A、コンパイラはを生成B::fooして、そのサブオブジェクトポインタからオブジェクトA* const subobjectを検索します。B* const thisしかしB::foo、の関係についての知識はありませんC

于 2012-12-26T18:07:29.247 に答える
0

あなたの例には2つの基本クラスがあるので(これは設計の問題/設計のにおいかもしれませんが、私はそれを確認します)、あなたが求めている実装を明示的に呼び出す必要がありA::foo()ますB:foo()

Bが実装を提供するだけのfoo()場合は、実装をAに移動することを検討します(純粋仮想関数の実装を提供できます)が、この場合でも、修飾名を使用して呼び出す必要があります。

于 2012-12-26T17:58:54.630 に答える