2009-06-06 2 views
3

Я просто хотел бы знать, является ли этот следующий блок кода полноценными в C++:Действительно ли это код на 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.

ответ

17

Нет, это недействительно. Вы не можете переопределить их отдельно, потому что они будут иметь одну и ту же подпись.

Об этом есть guru of the week.

+1

, и кроме этого не виртуальный дтор является тикающей бомбой. но это был не вопрос. :) – wilhelmtell

1

Квалифицированный имя A :: б не допускается в качестве имени члена класса С.

1

Он не должен компилировать из-за родителей, имеющих такое же имя функции. Кроме того, вы не должны перегружать функцию b более одного раза.

Если обратиться к виртуальной таблице, созданной для этого:

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

Вы видите, так как класс B имеет такое же имя функции, как класс А, то она перекрывает его, таким образом, у вас есть сейчас B :: B (), чтобы переопределить (поскольку он все еще чистый). Это связано с множественным наследованием. Как бы компилятор мог различаться между ними (они имеют одну и ту же подпись)? Как правило, это не сработает, потому что, как я уже сказал, компилятор не должен принимать решения, он должен сказать вам, что есть проблема.

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

+0

> Как бы компилятор мог различаться между двумя (они имеют одну и ту же подпись)? Но это случается также, например, когда у вас есть класс с несколькими базами, у которых есть какая-то общая родительская база (вам часто нужно использовать виртуальное наследование). Конечно, компилятор не может дифференцировать вызовы к общим методам (если мы не используем виртуальное наследование) и выдает ошибку двусмысленного вызова, но его можно легко решить путем динамического отображения этого экземпляра класса в базовый класс, который мы хотим. И да, я использую его на VS таким образом, и он работает без проблем. – RedDragCZ

+0

@RedDragCZ: Насколько я использую виртуальное наследование, это относится только к случаям, когда у вас есть подкласс, наследующий от того же базового класса. Если вы посмотрите на мигающую ссылку, предлагаемое решение - использовать так называемые вспомогательные классы. – tomzx

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)' 

И для чего это стоит, компилятор Комео ведет себя так же, но с сообщением еще более запутанной ошибки:

"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(); 
+0

Да, я знаю, что без разрешения того, что метод b() должен был называться, конечно, не будет работать, но нет проблем с downcasting экземпляра C, выделенного на кучу, а затем вызывая b() на нем, как ' dynamic_cast (c_instance_on_heap) -> b() '(что совершенно применимо, поскольку в моем собственном коде я использую интерфейсы A и B как интерфейсы). – RedDragCZ

+0

Но компилятор должен жаловаться на попытки объявить методы, а не ждать, пока метод будет доступен. Я не знаю, почему компиляторы используют это поведение. –

Смежные вопросы