[英]Does a virtual function override a non-virtual function of the same name in a base class?
以下标准是否符合要求? 你能举这个部分吗?
struct A
{
virtual void func() = 0;
};
struct B
{
void func(){}
};
struct C : public A, public B
{
virtual void func(){ B::func(); }
};
我在VS2010中得到了一个奇怪的编译器警告,它在等效但更复杂的代码中指向派生最多类中的func
声明: warning C4505: unreferenced local function has been removed
。 我不知道为什么编译器认为在类中声明的虚函数是本地的; 但是我不能在一个更简单的例子中重复这个警告。
我想出了一个小警告的重复案例。 假设它与函数隐藏有关,我认为我走错了路。 这是repro案例:
template<typename T>
struct C
{
int GetType() const;
virtual int func() const; // {return 4;} // Doing this inline removes the warning <--------------
};
template<typename T>
int C<T>::GetType() const
{
return 0;
}
template<>
int C<int>::GetType() const
{
return 12;
}
template<typename T>
int C<T>::func() const
{
return 3;
}
// Adding the following removes the warning <--------------------
// template<>
// int C<int>::func() const
// {
// return 4;
// }
我很确定这只是一个VS2010错误。
代码格式正确。 C::func
覆盖A::func
。 B::func
是一个不相关的函数。 规范如下(10.3 / 2):
如果虚拟成员函数
vf
在类Base
和Derived
类中声明,直接或间接从Base
Derived
,则具有相同名称的成员函数vf
,parameter-type-list,cv-qualification和ref-qualifier(或如果声明Base::vf
,那么Derived::vf
也是虚拟的(无论是否如此声明)并且它覆盖了111Base::vf
。
C::func
与A::func
同名, A::func
是虚拟的,因此C::func
会覆盖A::func
。 B::func
与A::func
无关; 我不知道规范中有任何语言明确地解决了这种情况。
Visual C ++ 11 Beta编译器不会为此代码发出任何警告或错误。
通常,链接器不能将虚函数作为死代码消除,因为它们的地址必须出现在vtable中。 但是,如果struct C
的vtable被确定为死代码(如果所有构造函数也是死代码,则可能发生这种情况),那么也可以消除最后剩余的引用。
因为函数是inline
声明的,所以这个死代码删除优化不必等到链接时间; 它可以由编译器完成。 标准说(见7.1.2节):
内联函数应在每个使用过的翻译单元中定义,并且在每种情况下都应具有完全相同的定义(3.2)。 [注意:在定义出现在翻译单元之前,可能会遇到对内联函数的调用。 - 结束注释]如果函数的定义在第一次声明为内联之前出现在翻译单元中,则程序格式不正确。 如果在一个翻译单元中内联声明具有外部链接的功能,则应在其出现的所有翻译单元中内联声明; 无需诊断。 具有外部链接的
inline
函数在所有翻译单元中应具有相同的地址。extern inline
函数中的static
局部变量始终引用同一个对象。extern inline
函数体中的字符串文字是不同翻译单元中的相同对象。 [注意:出现在默认参数中的字符串文字不在内联函数的主体中,因为该表达式用于来自该内联函数的函数调用中。 - 结尾注释]在extern inline
函数体内定义的类型在每个翻译单元中都是相同的类型。
如果编译器可以确定函数从未在此转换单元中使用,则它知道任何使用该函数的转换单元必须包含其自己的相同定义,并将生成代码。 因此它可以跳过代码生成,就像它根本没有外部链接一样。
然而,生成警告是完全没有意义的,因为会有大量的误报(当inline
函数使用了odr并且在其他编译单元中生成代码时)。
function
:已删除未引用的本地功能给定的函数是本地的,在模块的主体中没有引用; 因此,该功能是死代码。
编译器没有为这个死函数生成代码。
编译器静态地确定该函数未被使用,因此它不会为该函数生成代码并警告您有无用的代码。 比通常的未使用的变量警告更多涉及,但大致相同的效果:死代码气味。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.