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 。

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

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

你看,由于类 B 与类 A 具有相同的函数名,它会覆盖它,因此你现在有 B::b() 来覆盖(因为它仍然是纯的)。这是由于多重继承。编译器如何区分两者(它们具有相同的签名)?一般来说,这会失败,因为就像我刚才说的,编译器不应该做出决定,它应该告诉你有问题。

它在 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 回答