繁体   English   中英

虚函数是否覆盖基类中同名的非虚函数?

[英]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在类BaseDerived类中声明,直接或间接从Base Derived ,则具有相同名称的成员函数vf ,parameter-type-list,cv-qualification和ref-qualifier(或如果声明Base::vf ,那么Derived::vf也是虚拟的(无论是否如此声明)并且它覆盖了111 Base::vf

C::funcA::func同名, A::func是虚拟的,因此C::func会覆盖A::func B::funcA::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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM