该功能是否覆盖基本功能?

Gra*_*rak 16 c++ c++11

我有三个不同的编译器,我用来编译这段代码.其中一个(我最信任的那个)警告Derived中的函数隐藏了Base中的函数.其他编译器(一个是Visual C++)没有警告.如果我启用/ Wall或/ W4,Visual C++甚至不会发出警告.

我倾向于认为这是编译器中的一个错误,它会发出警告,因为它编译代码.如果它确实没有覆盖基函数,那么当我创建派生模板的实例时它应该给出错误.

任何人都可以确认这应该如何表现?

struct Base
{
   virtual void Func(float f) = 0;
};

template <typename T>
struct Derived : Base
{
   virtual void Func(T f){}
};

int main()
{
   Derived<float> d;
   d.Func(0);
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

什么时候Derived实例化float我得到意外的警告.当Derived被实例化与int我得到一个错误,符合市场预期.

vso*_*tco 7

它确实被覆盖了.您可以使用override关键字在C++ 11中轻松说服自己,如果不覆盖该函数,则不允许编译代码:

struct Base
{
   virtual void Func(float f) = 0;
   virtual ~Base() = default; // to silence warnings
};

template <typename T>
struct Derived : Base
{
   void Func(T f) override {} // will fail to compile if not overriding
};

int main()
{
   Derived<float> d;
   d.Func(0);
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

这里有实例.

请注意,在前C++ 11中,您可以virtual通过在派生类中更改其签名来意外隐藏基本函数,因此即使您标记派生函数virtual代码仍然编译,但不再是多态,请参见此处的此类示例.不幸的是,g ++没有提供任何警告,即使是-Wall -Wextra.这就是为什么override在编译时实际执行真正覆盖的更安全的方法.