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

Does a virtual function override a non-virtual function of the same name in a base class?

本文关键字:函数 基类 是否 覆盖      更新时间:2023-10-16

以下标准是否符合?你能引用这个部分吗?

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。我不知道为什么编译器认为在类中声明的虚拟函数是局部函数;但是我无法在更简单的示例中重现该警告。

编辑:

我想出了一个用于警告的小复制案例。我想我走错了路,假设它与功能隐藏有关。这是重现案例:

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::funcB::func是一个不相关的函数。 规范如下 (10.3/2(:

如果一个虚成员函数vf是在类Base和类Derived中声明的,直接或间接派生自Base,则成员函数vf与声明Base::vf具有相同的名称、参数类型列表、cv-限定符和ref限定符(或不存在相同(,则Derived::vf也是虚拟的(无论它是否如此声明(,并且它覆盖了111 Base::vf

C::funcA::func同名,A::func是虚拟的,因此C::func覆盖A::funcB::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:已删除未引用的本地函数

给定的函数是本地的,

不在模块主体中引用;因此,该函数是死代码。

编译器没有为此死函数生成代码。

编译器静态确定该函数

未使用,因此它不会为该函数生成代码,并警告您您有无用的代码。比通常未使用的变量警告更复杂一些,但效果大致相同:死代码闻起来。