clang выдает предупреждение при компиляции следующего кода:
struct Base
{
virtual void * get(char* e);
// virtual void * get(char* e, int index);
};
struct Derived: public Base {
virtual void * get(char* e, int index);
};
Предупреждение:
warning: 'Derived::get' hides overloaded virtual function [-Woverloaded-virtual]
(указанное предупреждение, конечно, должно быть включено).
Не понимаю почему. Обратите внимание, что раскомментирование того же объявления в Base закрывает предупреждение. Насколько я понимаю, поскольку две функции get () имеют разные сигнатуры, скрытия быть не может.
Лязг? Почему?
Обратите внимание, что это работает на MacOS X с последней версией Xcode.
clang --version
Apple LLVM version 5.0 (clang-500.1.74) (based on LLVM 3.3svn)
Обновление: такое же поведение с Xcode 4.6.3.
get
функцию-член с одним аргументом для объекта статического типаDerived
. Без объявления using то же самое привело бы к ошибке компиляции.Другой способ отключить предупреждение, сохранив неповрежденный интерфейс struct public:
struct Derived: public Base { virtual void * get(char* e, int index); private: using Base::get; };
Это запрещает потребителю
Derived
звонитьDerived::get(char* e)
во время отключения предупреждения:Derived der; der.get("", 0); //Allowed der.get(""); //Compilation error
источник
get
!Решение Р. Мартиньо Фернандеса совершенно справедливо, если вы действительно хотите ввести
get()
метод, принимающий один аргумент char * вDerived
область видимости.Фактически, в предоставленном вами фрагменте нет необходимости в виртуальных методах (поскольку Base и Derived не используют какие-либо методы с одинаковой сигнатурой).
Предполагая, что действительно существует потребность в полиморфизме, поведение сокрытия, тем не менее, может быть тем, что задумано. В этом случае можно локально отключить предупреждение Clang с помощью следующей прагмы:
#pragma clang diagnostic push #pragma clang diagnostic ignored "-Woverloaded-virtual" // Member declaration raising the warning. #pragma clang diagnostic pop
источник
const
об унаследованном методе, и clang все время был правильным. В случае сомнений доверяйте компилятору. Если вы сомневаетесь в компиляторе, доверяйте компилятору. :) +1 за то, что оба дали мне то, что я искал и в чем нуждался!Предупреждение означает, что в области класса Derived не будет функции void * get (char * e), потому что она скрыта другим методом с таким же именем. Компилятор не будет искать функцию в базовых классах, если производный класс имеет хотя бы один метод с указанным именем, даже если у него есть другие аргументы.
Этот пример кода не компилируется:
class A { public: virtual void Foo() {} }; class B : public A { public: virtual void Foo(int a) {} }; int main() { B b; b.Foo(); return 0; }
источник
b.Foo();
. Вам просто нужно написатьb.A::Foo();
.