Ana*_*rki 211 c++ overriding virtual-functions
使用下面给出的结构定义......
struct A {
virtual void hello() = 0;
};
Run Code Online (Sandbox Code Playgroud)
方法#1:
struct B : public A {
virtual void hello() { ... }
};
Run Code Online (Sandbox Code Playgroud)
方法#2:
struct B : public A {
void hello() { ... }
};
Run Code Online (Sandbox Code Playgroud)
这两种覆盖hello函数的方法有什么区别吗?
Jam*_*lis 172
它们完全一样.除了第一种方法需要更多打字并且可能更清晰之外,它们之间没有区别.
Cli*_*ord 81
函数的"虚拟性"是隐式传播的,但是如果virtual关键字没有显式使用,我使用的至少一个编译器会生成警告,所以如果只是为了保持编译器安静,你可能想要使用它.
从纯粹的风格角度来看,包括virtual关键字清楚地向用户宣传该功能是虚拟的.这对于任何进一步细分B而不必检查A的定义的人来说都很重要.对于深层次的层次结构,这变得尤为重要.
R S*_*ahu 50
virtual派生类中不需要该关键字.以下是C++草案标准(N3337)(强调我的)的支持文档:
10.3虚函数
2如果
vf在类Base和类中声明了虚方法成员函数,该类Derived直接或间接地从具有相同名称Base的成员函数派生vf,参数类型列表(8.3.5),cv-qualification和ref-qualifier(或者没有相同的),Base::vf如果声明,那么Derived::vf也是虚拟的(无论是否如此声明)并覆盖Base::vf.
Col*_*ett 31
不,不需要virtual派生类的虚函数覆盖上的关键字.但值得一提的是一个相关的陷阱:未能覆盖虚函数.
该重写失败,如果你打算重写在派生类中的虚函数,但做出一个错误的签名,以便它声明了一个新的和不同的虚函数发生.此函数可能是基类函数的重载,或者名称可能不同.无论您是否virtual在派生类函数声明中使用关键字,编译器都无法告诉您打算从基类重写函数.
然而,幸运的是,C++ 11 显式覆盖语言特性解决了这个缺陷,该特性允许源代码清楚地指定成员函数旨在覆盖基类函数:
struct Base {
virtual void some_func(float);
};
struct Derived : Base {
virtual void some_func(int) override; // ill-formed - doesn't override a base class method
};
Run Code Online (Sandbox Code Playgroud)
编译器将发出编译时错误,并且编程错误将立即显而易见(可能Derived中的函数应该将a float作为参数).
参见WP:C++ 11.
当您virtual在派生类中编写或省略它时,编译器没有区别.
但是你需要查看基类来获取这些信息.因此virtual,如果您想向人类展示此功能是虚拟的,我建议在派生类中添加关键字.