virtual 函数指定符
< cpp | language
virtual 指定符指定非静态成员函数为虚并支持动态绑定。它只能出现在非静态成员函数首个声明(即它声明于类定义中时)的 decl-specifier-seq 中。
解释
虚函数是在派生类中行为可被覆写的成员函数。与非虚函数相反,覆写的行为会受到保留,即使没有关于该类实际类型的编译时信息。若使用到基类的指针或引用处理派生类,则对被覆写虚函数的调用,将会调用定义于派生类的行为。若使用有限定名称查找(即若函数名出现在作用域解决运算符 ::
的右侧),则此行为被压制。
#include <iostream>
struct Base {
virtual void f() {
std::cout << "base\n";
}
};
struct Derived : Base {
void f() override { // 'override' 可选
std::cout << "derived\n";
}
};
int main()
{
Base b;
Derived d;
// 通过引用调用虚函数
Base& br = b; // br 的类型是 Base&
Base& dr = d; // dr 的类型也是 Base&
br.f(); // 打印 "base"
dr.f(); // 打印 "derived"
// 通过指针调用虚函数
Base* bp = &b; // bp 的类型是 Base*
Base* dp = &d; // dp 的类型也是 Base*
bp->f(); // 打印 "base"
dp->f(); // 打印 "derived"
// 非虚函数调用
br.Base::f(); // 打印 "base"
dr.Base::f(); // 打印 "base"
}
细节
consteval
虚函数不能覆写非 consteval
虚函数或被它覆写。
若某成员函数 vf
在类 Base
中声明为 virtual
,且某个直接或间接从 Base
派生的类 Derived
拥有下列几点与之相同的成员函数声明
- 名称
- 参数列表(但非返回类型)
- cv 限定符
- 引用限定符
则类 Derived
中的此函数亦为虚(无论是否于其声明使用关键词 virtual
)并覆写 Base::vf (无论是否于其声明使用词 override
)。
要覆写的 Base::vf
不需要可见(可声明为 private ,或用私有继承继承)。
class B {
virtual void do_f(); // 私有成员
public:
void f() { do_f(); } // 公开继承
};
struct D : public B {
void do_f() override; // 覆写 B::do_f
};
int main()
{
D d;
B* bp =