3

次のコード ブロックが C++ で完全に有効かどうかを知りたかっただけです。

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

class B
{
public:
   virtual bool b() = 0;
};

class C: public A, public B
{
public:
  virtual bool A::b()
  {
    return true;
  }

  virtual bool B::b()
  {
    return false;
  }
};

VS2008 を使用するとエラーなしでコンパイルされますが、GCC (MinGW) 3.4.5 では次のようなエラーが発生します。

cannot declare member function `A::b' within `C'

仮想メソッドが実装されている行。これが一般的に無効と見なされ、C++ 標準ではコードが禁止されている (VS では、MS の標準化されていない魔法のおかげで機能する) のか、GCC のバグまたはサポートされていない言語機能のみなのか、興味がありました。

4

4 に答える 4

17

いいえ、有効ではありません。それらは同じ署名を持つため、そのように個別にオーバーライドすることはできません。

それについての今週の第一人者があります。

于 2009-06-06T17:06:43.803 に答える
1

修飾名A::bは、クラスCのメンバーの名前として許可されていません。

于 2009-06-06T17:07:52.507 に答える
1

親が同じ関数名を持っているため、コンパイルしないでください。さらに、関数bを2回以上オーバーロードすることは想定されていません。

このために作成された仮想テーブルを参照する場合:

0(beginning of vtable) - A::b() -> B::b()

ご覧のとおり、クラスBはクラスAと同じ関数名を持っているため、それをオーバーライドします。したがって、オーバーライドするB :: b()があります(まだ純粋であるため)。これは、複数の継承が原因です。コンパイラーはどのようにして2つを区別することができますか(それらは同じ署名を持っています)?一般に、これは失敗します。これは、先ほど述べたように、コンパイラーが決定を行うことを想定していないため、問題があることを通知することになっているためです。

VSでコンパイルしますが、(実際に作成されたファイルに含まれている)実行してみましたか?コンパイラが怠惰で、使用されていないクラスでエラーをポップしない場合があります。

于 2009-06-06T17:19:13.633 に答える
0

参考までに、VC はbメソッドを使用しようとした場合にのみエラーを出します。

C:\temp\test.cpp(33) : error C2668: 'C::b' : ambiguous call to overloaded function
      C:\temp\test.cpp(23): could be 'bool C::b(void)'
      C:\temp\test.cpp(18): or       'bool C::b(void)'
      while trying to match the argument list '(void)'

価値のあることとして、Comeau のコンパイラは同様に動作しますが、さらに紛らわしいエラー メッセージが表示されます。

"C:\temp\test.cpp", line 33: error: no instance of overloaded function "C::b"
          matches the argument list
            object type is: C
      bool z = c.b();
于 2009-06-06T19:54:39.493 に答える