Виртуальные методы в виртуальном базовом классе - PullRequest
8 голосов
/ 07 июля 2011

Что-то, что смущало меня в отношении наследования виртуальных базовых классов ... Учитывая следующие классы:

class A
{
  virtual void foo() = 0;
}
class B : virtual A
{
  void foo() { /* do X */ }
}
class C : virtual A
{
  void foo() { /* do Y */ }
}
class D : B, C
{
}

Будет ли это компилироваться?Если так, что будет результатом следующего кода:

D d;
A* a = &d;
a->foo();

Ответы [ 4 ]

7 голосов
/ 07 июля 2011

Не должно компилироваться, функция foo будет неоднозначной. Поскольку A :: foo () является чисто виртуальной функцией, неоднозначность должна быть устранена.

4 голосов
/ 07 июля 2011

Не скомпилируется. GCC:

error: no unique final overrider for ‘virtual void A::foo()’ in ‘D’

Вы могли бы довольно быстро это выяснить.

То же самое с icc:

error #361: override of virtual function "A::foo" is ambiguous
4 голосов
/ 07 июля 2011

Он не скомпилируется по трем причинам, ни одна из которых не имеет никакого отношения к виртуальному наследованию (ну, может быть, последняя)

  1. Вы забыли точки с запятой после определений классов

  2. Ваше наследство является частным

  3. D::foo() является неоднозначным, если явно не переопределено

Кстати, само определение D неверно сформировано, а не только тот факт, что вы пытаетесь его использовать. Я имею в виду, если бы ваша функция main() была пуста, она все равно не скомпилировалась бы.

И "Это скомпилируется?" имеет очевидный ответ «Почему бы тебе не попробовать?»

Цитата из стандарта: 10.3.10

В следующем примере показана функция, которая не имеет уникального окончательное переопределение:

 struct A {
 virtual void f();
 };
 struct VB1 : virtual A { // note virtual derivation
 void f();
 };
 struct VB2 : virtual A {
 void f();
 };
 struct Error : VB1, VB2 { // ill-formed
 };
3 голосов
/ 07 июля 2011

Нет, не будет:

diamond.cpp:24:7: error: request for member ‘foo’ is ambiguous
diamond.cpp:13:8: error: candidates are: virtual void C::foo()
diamond.cpp:8:8: error:                 virtual void B::foo()

Это называется Алмазная проблема , см. http://en.wikipedia.org/wiki/Diamond_problem

...