- 先决条件
- 前言
- 演示示例
- virtual 关键字的作用
- 虚函数的规则
- 参考与拓展
- 了解 C++ 中的多态这个概念。
virtual 关键字是面对对象中,用于修饰类中的成员函数的关键字。被 virtual 关键字修饰的函数叫做虚函数。而虚函数本身是实现 C++ 多态的一种方式。
在上图中,我们看到,虚函数属于运行时多态。
那么为什么要使用 virtual 关键字呢?它的作用是什么呢?
演示示例下面先来看看 virtual 关键字的使用。
在这个示例中,我们演示不使用 virtual 关键字时会发生的问题。
#includeusing namespace std; class Human { public: void YourRace() { cout << "我是人类" << endl; } }; class Aisan : public Human { public: void YourRace() { cout << "我是黄种人(亚洲人)" << endl; } }; int main() { Human *h; Aisan a; h = &a; h->YourRace(); // 我是人类 }
上面的代码描述的是,*h 为基类的一个指针,它被指向了 Human 的派生类的一个对象 a(即 h = &a ;)。
在 C++ 中,基类指针可以指向派生类的对象,但是基类指针不能访问派生类的成员。所以我们看到当指向 a 的基类指针调用 YourRace 函数时,它实际调用的是基类的函数,而不是我们期望的派生类的 YourRace 函数。
那么如果要解决这个问题,即想要调用派生类的 YourRace 函数,我们只需要在基类的 YourRace 函数前面增加 virtual 关键字即可,它的语法是:virtual void YourRace(){...};。
#includeusing namespace std; class Human { public: virtual void YourRace() { cout << "我是人类" << endl; } }; class Aisan : public Human { public: void YourRace() { cout << "我是黄种人(亚洲人)" << endl; } }; int main() { Human *h; Aisan a; h = &a; h->YourRace(); // 我是黄种人(亚洲人) }
可以看到,本段代码仅仅是新增了一个 virtual 关键字,就实现了调用派生类成员函数的功能。
virtual 关键字的作用可以看到,增加了 virtual 关键字后,实际上,编译器是在运行时才确定对象的类型,执行动态链接,然后绑定函数调用,所以这又叫动态绑定。
比如在上面的第二段代码中,h 实际指向的对象是 a,a 的类型是 Aisan,所以最终调用的是 Aisan 类的 YourRace 函数。
在基类中使用 virtual 关键字,表明基类要求派生类重写这个函数。当使用指针或者应用调用虚函数时,调用被动态绑定到运行时才发生,也就是根据被绑定的对象的类型不同,执行具体的版本,就像上面所展示的那样。
【注】非虚函数的解析发生在编译过程。
虚函数的规则- 虚函数是基类的成员函数(只能出现在类内),其派生的同名函数用于重写覆盖(override)其内容。
- virtual 不能修饰静态成员。
- virtual 不能修饰构造函数,但可以修饰析构函数,并且基类通常都应该定义一个 virtual 的析构函数。
- 派生类继承的基类里面的虚函数,在派生类中隐式的,也是虚函数。
- C++ virtual function【javatpoint】
- Virtual Function in C++【geeksforgeeks】
- 为什么静态static成员函数不能成为virtual虚函数
- 析构函数可以为virtual,构造函数则不能。原因?
- Why Destructors in C++ can be virtual but constructors cannot be virtual?
- 为什么要用基类指针指向派生类对象?
- 《Primer C++》



