page contents

C++虚函数注意事项以及构成多态的条件

C++ 虚函数对于多态具有决定性的作用,有虚函数才能构成多态。这节我们来重点说一下虚函数的注意事项。

C++ 虚函数对于多态具有决定性的作用,有虚函数才能构成多态。这节我们来重点说一下虚函数的注意事项。

1) 只需要在虚函数的声明处加上 virtual 关键字,函数定义处可以加也可以不加。

2) 为了方便,你可以只将基类中的函数声明为虚函数,这样所有派生类中具有遮蔽关系的同名函数都将自动成为虚函数。


3) 当在基类中定义了虚函数时,如果派生类没有定义新的函数来遮蔽此函数,那么将使用基类的虚函数。

4) 只有派生类的虚函数覆盖基类的虚函数(函数原型相同)才能构成多态(通过基类指针访问派生类函数)。例如基类虚函数的原型为virtual void func();,派生类虚函数的原型为virtual void func(int);,那么当基类指针 p 指向派生类对象时,语句p -> func(100);将会出错,而语句p -> func();将调用基类的函数。

5) 构造函数不能是虚函数。对于基类的构造函数,它仅仅是在派生类构造函数中被调用,这种机制不同于继承。也就是说,派生类不继承基类的构造函数,将构造函数声明为虚函数没有什么意义。

6) 析构函数可以声明为虚函数,而且有时候必须要声明为虚函数,这点我们将在下节中讲解。

构成多态的条件

站在“学院派”的角度讲,而多态是指通过基类的指针既可以访问基类的成员,也可以访问派生类的成员。

下面是构成多态的条件:

  • 必须存在继承关系;

  • 继承关系中必须有同名的虚函数,并且它们是覆盖关系(函数原型相同)。

  • 存在基类的指针,通过该指针调用虚函数。


下面的例子对各种混乱情形进行了演示:



  1. #include <iostream>

  2. using namespace std;

  3. //基类Base

  4. class Base{

  5. public:

  6. virtual void func();

  7. virtual void func(int);

  8. };

  9. void Base::func(){

  10. cout<<"void Base::func()"<<endl;

  11. }

  12. void Base::func(int n){

  13. cout<<"void Base::func(int)"<<endl;

  14. }

  15. //派生类Derived

  16. class Derived: public Base{

  17. public:

  18. void func();

  19. void func(char *);

  20. };

  21. void Derived::func(){

  22. cout<<"void Derived::func()"<<endl;

  23. }

  24. void Derived::func(char *str){

  25. cout<<"void Derived::func(char *)"<<endl;

  26. }

  27. int main(){

  28. Base *p = new Derived();

  29. p -> func();  //输出void Derived::func()

  30. p -> func(10);  //输出void Base::func(int)

  31. p -> func("http://c.biancheng.net");  //compile error

  32. return 0;

  33. }

在基类 Base 中我们将void func()声明为虚函数,这样派生类 Derived 中的void func()就会自动成为虚函数。p 是基类 Base 的指针,但是指向了派生类 Derived 的对象。

语句
p -> func();调用的是派生类的虚函数,构成了多态。

语句
p -> func(10);调用的是基类的虚函数,因为派生类中没有函数覆盖它。

语句
p -> func("http://c.biancheng.net");出现编译错误,因为通过基类的指针只能访问从基类继承过去的成员,不能访问派生类新增的成员。

什么时候声明虚函数

首先看成员函数所在的类是否会作为基类。然后看成员函数在类的继承后有无可能被更改功能,如果希望更改其功能的,一般应该将它声明为虚函数。如果成员函数在类被继承后功能不需修改,或派生类用不到该函数,则不要把它声明为虚函数。

attachments-2021-04-l2sCkAFS6082ba9f6a79a.jpg

  • 发表于 2021-04-23 20:17
  • 阅读 ( 609 )
  • 分类:C/C++开发

0 条评论

请先 登录 后评论
小柒
小柒

1470 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1470 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章