虚函数与纯虚函数(详细讲解)

Posted on 8/4/2022 at 12:00:00 上午

同样,在newB的时候,A的构造函数被调用,但是在A的构造函数中,被调用的是A::foo()而不是B::foo。

参考资料1深度探索C++对象模型,StanleyB.Lippman,侯捷译2DesignPatterns,ElementsofReusableObject-OrientedSoftware,GOF。

如果在派生类中没有对基类的虚函数重新定义,则派生类简单地继承其直接基类的虚函数。

*构造函数:不可以,构造函数不依赖对象的调动*析构函数:可以*友元函数:不可以,C++不支持友元函数的继承,**1.****虚函数**·虚表是怎么实现的?虚表存放在哪里?·虚表中的数据是在什么时候确定的?·对象中的虚表指针又在什么时候赋值的?我们很难通过C++语言本身来找到答案。

C++纯虚函数定义纯虚函数是在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义自己的实现方法。

例如飞行器的飞行动作,逻辑上每种飞行器都必须提供为其特殊设计的个性化飞行行为,而不应该有任何一种”通用的飞行方式”;3.使用一个基类类型的指针或者引用,来指向子类对象,进而调用经由子类复写了的个性化的虚函数,这是C++实现多态性的一个最经典的场景;4.基类提供的纯虚函数的实现版本,并非为了多态性考虑,因为指向子类对象的基类指针和引用无法调用该版本。

另外,每个使用虚函数表的类都有*__vptr指针,从而每个类对象都会多一个指针的空间。

,什么是虚函数(如果不知道虚函数为何物,但有急切的想知道,那你就应该从这里开始)简单地说,那些被virtual关键字修饰的成员函数,就是虚函数。

比如在微软的MFC类库中,你会发现很多函数都有virtual关键字,也就是说,它们都是虚函数。

纯虚函数在基类中的实现跟多态性无关,它只是提供了一种语法上的便利,在变化多端的应用场景中留有后路;5.虚函数和普通的函数实际上是存储在不同的区域的,虚函数所在的区域是可被覆盖(也称复写override)的,每当子类定义相同名称的虚函数时就将原来基类的版本给覆盖了,另一侧面也说明了为什么基类中声明的虚函数在后代类中不需要另加声明一律自动为虚函数,因为它所存储的位置不会发生改变。

虚继承、虚函数**相同之处:**都利用了虚指针(均占用类的存储空间)和虚表(均不占用类的存储空间)**不同之处:**虚继承(1)虚基类依旧存在继承类中,只占用存储空间(2)虚基类表存储的是虚基类相对直接继承类的偏移虚函数(1)虚函数不占用存储空间(2)虚函数表存储的是虚函数地址模板类、成员模板、虚函数模板类中可以使用虚函数一个类(无论是普通类还是类模板)的成员模板(本身是模板的成员函数)不能是虚函数抽象类、接口类、聚合类**抽象类:**含有纯虚函数的类**接口类:**仅含有纯虚函数的抽象类**聚合类:**用户可以直接访问其成员,并且具有特殊的初始化语法形式。

通过该指针变量调用此虚函数,此时调用的就是指针变量指向的对象的同名函数。

在以该类为基类的派生类中,也不能出现这种同名函数。

难怪有人甚至称虚函数是C++语言的精髓。

,”

那这个类信息是什么呢?我们来看下面几个类:classno_virtualderivedtd;编译生成的汇编代码如下:movDWORDPTR_td$esp+24,OFFSETFLAT:??_7derived@@6B@;derived::`vftable由编译器的注释可知,此时PTR_td$esp+24中存储的就是derived类的VTABLE地址。

定义纯虚函数就是为了让基类不可实例化化因为实例化这样的抽象数据结构本身并没有意义。

当程序执行到pb->bar时,已经能够判断pb指向的具体类型了:*如果pb指向B的对象,可以获取到B对象的vptr,加上偏移值8((char*)vptr+8),可以找到B::bar。

虚函数的使用方法是:1.在基类用virtual声明成员函数为虚函数。

而构造函数是用来实例化一个对象的,通俗来讲就是为对象内存中的值做初始化操作。

Posted on 星期四, 8月 4th, 2022 at 上午12:00 In 域名主机 | Comments RSS

Leave a Reply