我使用三种不同的编译器来编译此代码。其中之一(我最不信任的一个)警告说,“派生”中的功能会隐藏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;
}
当Derived
与实例化float
,我得到了意想不到的警告。当Derived
与实例int
我得到一个错误,符合市场预期。
它确实被覆盖了。您可以使用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;
}
这里的例子。
请注意,在C ++ 11之前的版本中,您可以virtual
通过在派生类中更改其签名来意外隐藏基本函数,因此,即使您标记了派生函数,virtual
该代码仍然可以编译,但不再是多态的,请参见此处的示例。不幸的是,即使使用,g ++也不会提供任何警告-Wall -Wextra
。这就是为什么override
在编译时实际执行true覆盖的更安全的方法。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句