这是有效的C ++代码吗?

时间:2009-06-06 17:02:03

标签: c++ multiple-inheritance

我只想知道下面的代码块是否在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 个答案:

答案 0 :(得分:17)

不,它无效。你不能像这样单独覆盖它们,因为它们具有相同的签名。

有一个guru of the week

答案 1 :(得分:1)

不允许使用限定名A :: b作为C类成员的名称。

答案 2 :(得分:1)

由于父级具有相同的功能名称,因此不应编译。此外,您不应该多次重载函数b。

如果您参考为此创建的虚拟表:

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

你知道,因为B类与A类具有相同的功能名称,所以它会覆盖它,因此你现在可以覆盖B :: b()(因为它仍然是纯粹的)。这是由于多重继承。编译器如何能够在两者之间进行区分(它们具有相同的签名)?一般来说,这会失败,因为正如我刚才所说,编译器不会做出决定,它应该告诉你存在问题。

它在VS上编译,但您是否尝试过运行它(包含在实际创建它的文件中)?有时,编译器是惰性的,不会在未使用的类上弹出错误。

答案 3 :(得分:0)

就像FYI一样,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();