c ++重载虚函数警告叮当?

编译以下代码时,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中取消注释相同的声明会closures警告。 我的理解是,由于get()函数具有不同的签名,因此不能隐藏。

是铿锵的吗? 为什么?

注意这是在MacOS X上运行最新版本的Xcode。

 clang --version Apple LLVM version 5.0 (clang-500.1.74) (based on LLVM 3.3svn) 

更新:与Xcode 4.6.3相同的行为。

这个警告是为了防止在意图覆盖时意外隐藏重载。 考虑一个稍微不同的例子:

 struct chart; // let's pretend this exists struct Base { virtual void* get(char* e); }; struct Derived: public Base { virtual void* get(chart* e); // typo, we wanted to override the same function }; 

这是一个警告,并不一定意味着这是一个错误,但它可能表明一个。 通常这样的警告有一种更明确的方式closures它们,让编译器知道你打算写你写的东西。 我相信在这种情况下,你可以做到以下几点:

 struct Derived: public Base { using Base::get; // tell the compiler we want both the get from Base and ours virtual void * get(char* e, int index); }; 

R. Martinho Fernandes的解决scheme是完全有效的,如果你真的想把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 

警告意味着在Derived类的范围内不会有void * get(char * e)函数,导致它被另一个同名的方法隐藏。 如果派生类至less有一个具有指定名称的方法,即使它具有其他参数,编译器也不会在基类中search函数。

此示例代码不会编译:

 class A { public: virtual void Foo() {} }; class B : public A { public: virtual void Foo(int a) {} }; int main() { B b; b.Foo(); return 0; } 

禁用保持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