C++ virtual :推迟指针指向的决定

virtual根本原理

virtual 无论是函数,还是类继承中,他的真实功能就是推迟指针指向的决定

将在编译期的决定推迟到运行时决定,于是就有了多态的实现,多态的原理便是运行时的动态绑定

虚基类的继承是的类变量的指针可以推迟指向,而解决子类的二义性的问题以及存储浪费问题

编译期:虚函数的函数名符号指向是空的

运行期:虚函数的指针指向对象域,而不是类域

什么函数可以是虚函数

  1. 一般成员函数可以是
  2. 构造函数不能是虚函数
  3. 析构函数可以是虚函数

一般虚函数成员

  • 声明:virtual return_type func_name(formal_parameter_list)
  • 声明只能出现在类定义中的函数原型声明中
  • 在派生类中可以对基类的成员函数覆盖(千万不要重写继承而来的非虚函数,因为达不到多态的效果)
  • 虚函数一般不声明为内联函数,因为对虚函数的调用是动态的,而内联函数处理是编译期静态的

另外,1.派生类重写覆盖基类的虚函数时,也会被定义为虚函数,无论函数声明时是否加了virtual关键字

2.派生类中的虚函数重载还会隐藏基类的同名函数的其他重载显示(暂不清楚为什么)

故,一般派生类覆盖虚函数基函数时,一般怎加virtual关键字,提高程序可读性

虚析构函数

使用场景:允许他人使用基类的指针调用对象(基类对象或派生类对象)的析构函数,就需要使用虚析构函数——这也是应该做的,delete会正常运行;相反,如果不用虚析构函数,delete行为将是不可预测的,因为这个时候基类对象指针指向的对象函数表里存储的析构函数指针静态绑定到了基类的析构函数,在使用多态时,我们基类指针操作多态的派生类对象时,基类的析构函数不会释放派生类对象的相关的内存空间,会导致内存泄漏。

virtual关键字的实现,动态绑定实现窥览

虚表

每个多态的类都有一个虚表(virtual table),虚表中有当前类中的各个虚函数的入口地址,每个对象有一个指向当前类的虚表的指针(vptr),多态实现基于虚表,virtual关键字是告诉编译期,哪一些函数入口地址要放到虚表,运行时确定虚表的值和,调用时根据虚表运行初始化的值找到函数入口地址。

此文章部分内容是清华大学 郑颖老师参与的C++课程 课程地址的笔记与思考内容,如果教程说的你比较模糊的话,可以去看看课程和例子

BTW:这篇博客适合已经学过的再次思考和回忆,对初学者不建议,可能会晕

发布了17 篇原创文章 · 获赞 1 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/TowerOs/article/details/103947275