首页 > 编程语言 >C++虚函数

C++虚函数

时间:2022-10-05 22:24:02浏览次数:62  
标签:函数 继承 C++ 编译器 Base public 指针

C++三大特性:封装、继承、多态

在这里谈下多态,多态指的是在类之间存在继承关系时,有的函数声明为virtual函数,当我们将子类指针或引用转化为父类指针或引用时,调用某个虚函数时调用的是子类的虚函数。

编译器对于这种虚函数是在对象中存放了一个指针,这个指针指向一个表格,表格称之为虚函数表,在x86下,表格中的内容为多个连续的指针,这些指针指向一个个函数,当调用对象的虚函数时,会从这个表格中根据这个函数所在的顺序作为index从表格中取出指针,再调用这个函数。而index是在编译期即可确定的。

抽象模块成为一个类,再继承类的方式,然后在父类函数中有公共方法,在子类函数中有特定方法,在C++中经常用到。

还有一种方式:是虚基类,在抽象的父类中,不实现任何的方法,只保留接口,如下:

class A

{

public:

  virtual void virtuFunc1()=0;

};

如下编写代码如 A a;因为类A是个虚函数接口,只能使用A *a 这种方式,因为此时类A是个抽象类接口,没有具体实现。

如上形式中我们不需要也无法实现类A中的函数virtuFunc1,而可以在子类中实现此方法。

class B : public A

{

public:

  virtual void virtuFunc1()

  {

    printf("B\n");

  }

};

如上,在B类中实现了virtuFunc1方法,需要注意的是如果在B类中不实现此方法,同样也无法编写B b这样的代码,当前已经编写了,所以可以编写B b的代码。

我们可以在不同的模块,或者在不同的类中抽象出一个抽象类接口,不实现任何的方法。这样可以将不同的模块组合在一起,使用同一个接口去处理代码,方便编写模块。

这些虚函数都是通过虚函数表来实现的。

后续还有V形继承,还有菱形继承。

V形继承如基类A,基类B,类C继承于A与B,如果类A与类B中都存在虚函数,那么类C中就存在两个虚函数表指针,这也是比较简单的结构,如:

class C : public A, public B

{

};

使用如下语句如C* c = new C;   A* a = c; 编译器编译这条语句时,a变量值与c变量的值是一样的,直接进行转换,编译器生成的代码中,a变量直接赋值为c变量,如果使用这条语句 B* b = c;编译器编译这条语句时,会将c变量的值加一个偏移值再赋值给b,这个偏移值是编译器计算出来的,偏移值是类A所占的大小,这个大小包括类A所占的局部变量以及一个指向虚函数表的指针的大小,这个大小在32位程序中为4字节。

菱形继承比较复杂,还是按照上面的例子,如果A类与B类都继承自一个Base类,类中存在变量,那么当类D继承自A和B时,而A和B继承自Base类,这种情况如果画图那么就是菱形的,所以叫做菱形继承,出现这种情况,就需要使用虚继承,如下:

class C:  virtual public A, virtual public B

{

};

如果不使用虚继承,那么当C继承A和B时,A、B又继承自Base,那么此时C中继承自Base中的变量就存在两份,编译器编译代码时会提示变量重复冲突,因为不知道C中的同名变量来自于A(继承自Base)还是来自于B(来自于Base),所以需要使用虚继承。

虚继承的实现方式是在对象内部使用了相对偏移来指向变量,这个后续补充。

 

标签:函数,继承,C++,编译器,Base,public,指针
From: https://www.cnblogs.com/ps12345678/p/16756583.html

相关文章

  • OpenCV-Python-C++ 全套视频详讲
    更多资料请关注公众号:计算机视觉与图形学实战​​2021OpenCV-C++课程实践(理论与实践)​​​​2021年OpenCV-Python从入门到实战全套课程(附带课程课件资料+课件笔记)​​​​......
  • 【机器学习中的矩阵求导】(八)标量函数f(x)的雅克比矩阵(迹函数)
    学习总结交换律:,需要满足、同维度行列式微分:文章目录​​学习总结​​​​一、标量函数的雅克比函数​​​​二、关于迹函数的性质​​​​2.1常用性质​​​​2.2迹函数的......
  • C++complex 中学到的知识
    #ifndef__COMPLEX__#define__COMPLEX__classComplex{ public: //传值 complex(doubler=0,doublei=0) :re(r),im(i) {} complex&operator+......
  • C++/Python混合编程
    以C++为底层基础,Python作为上层建筑,共同搭建起高性能、易维护、可扩展的混合系统。Python本身就有C接口,可以用C语言编写扩展模块,把一些低效耗时的功能改用C实现......
  • 【c++基础】从json文件提取数据
    前言标注数据导出文件是json格式的,也就是python的dict格式,需要读取标注结果,可以使用c++或者python,本文使用c++实现的。JsonCpp简介JsonCpp是一种轻量级的数据交换格式,是个跨......
  • 【C语言_15】自定义函数和math库函数详解篇!
    一.函数的概念1.什么是函数?函数就是一段封装好的,可以重复使用的代码,它使得我们的程序更加模块化,不需要编写大量重复的代码。函数可以提前保存起来,并给它起一个独一无二的名......
  • 在C语言下Socket函数使用
    Socket介绍Socket中文意思是“插座”,在Linux环境下,用于表示进程间网络通信的特殊文件类型。本质为内核借助缓冲区形成的伪文件。既然是文件,那么理所当然的,我们可以使用文......
  • C++的基本数据类型
    C++的基本数据类型C++的数据类型可分为:1. 布尔类型:false0 true 12. 字符类型:可分为三种,char、signedchar、unsignedchar,其表现形式只是分为有符号和无符号,字符......
  • EffectiveC++中文版(第三版) pdf
    高清扫描版下载链接:https://pan.baidu.com/s/1I1w2alIPQH1GJ32lz0MoaA点击这里获取提取码 ......
  • 【优化调度】基于粒子群算法求解单一水库优化调度(目的函数总发电量)附matlab代码
    ✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。......