"静态成员函数覆盖基类中的虚函数"被gcc和clang抓住但不是VC ++

时间:2017-02-19 19:57:57

标签: c++ gcc visual-c++ clang virtual-functions

很可能人们不希望编译此示例:

#include <iostream>

class C {
public:
    virtual void Foo() {
        std::cout << "From C\n";
    }
};

class D : public C {
public:
    static void Foo() {
        std::cout << "From D\n";
    }
};

int main() {
    D d;
    d.Foo();
    return 0;
}

它确实无法在gcc和clang中编译(错误&#34;静态成员函数覆盖基类中的虚函数&#34;)。但是,它确实在Visual C ++中编译,在运行时将从D 说成控制台。即使最新的VC ++ RC 2017编译器(v141)带有选项 ISO C ++最新草案标准(/ std:c ++ latest) / permissive - ({{3} })打开了。

哪个编译器是对的?这是标准的错误吗?如果是这样,这是否意味着VC ++在这种情况下不遵循标准?

2 个答案:

答案 0 :(得分:3)

这绝对是一个MSVC错误。 ISO C ++不允许这样做。

class.static.mfct/2(强调我的):

  

[注意:静态成员函数没有this指针。 - 结束注释] 静态成员函数不应是虚拟的。的有   不应该是具有相同的静态和非静态成员函数   名称和相同的参数类型([over.load]) ...

答案 1 :(得分:1)

10.3:2 声明D::Foo必须是虚拟的(即使没有声明)。

  

如果在类Base和a中声明了虚拟成员函数vf   class派生,直接或间接来自Base,一个成员   函数vf,同名,参数类型列表(8.3.5),   与Base :: vf一样的cv-qualification和ref-qualifier(或不存在)   声明,然后Derived :: vf也是虚拟的(无论是否是这样   声明)并覆盖111 Base :: vf ...

9.4.1:2 声明它不能是虚拟的

  

[注意:静态成员函数没有this指针(9.3.2)。   -end note]静态成员函数不应是虚拟的。应该   不是具有相同名称的静态和非静态成员函数   和相同的参数类型(13.1)。静态成员函数应该   不要声明为const,volatile或const volatile。