码迷,mamicode.com
首页 > 编程语言 > 详细

C++中多态

时间:2017-11-13 20:00:05      阅读:196      评论:0      收藏:0      [点我收藏+]

标签:效率   实现   rtu   nbsp   初始化   自动   替换   函数指针   虚函数   

C++中多态的实现原理

当类中声明虚函数时,编译器会在类中生成一个虚函数表

虚函数表是一个存储类成员函数指针的数据结构

虚函数表是由编译器自动生成与维护的

virtual成员函数会被编译器放入虚函数表中 

存在虚函数时,每个对象中都有一个指向虚函数表的指针(vptr指针)

C++内存模型中,会将对象中的成员变量和成员方法分开存储,同时在成员函数中第一个参数的位置添加一个this指针。

类对象中的普通成员变量,struct变量具有相同的内存布局和字节对齐方式。

类对象中的静态成员变量,存储在全局数据区(我也不知道存在内存的什么位置,不知道是不是和那些常量以及字符串存储在同一位置)

类中的成员方法,存储在代码段中,同时在静态联编的时候,会将同一个类中的函数重载进行函数名称的替换(具体方式应该是函数名称+参数类型)。

但是,如果一个类中加了virtual关键字,C++编译器会有另外一种方式来进行上面描述的安排,会在struct中添加一个vptr指针(这就是为什么在使用virtual关键字之后在使用sizeof操作符会多4个字节的原因)

如果一个类中使用virtual关键字,在用类定义对象的时候,会在对象中添加一个vptr指针属性(这个操作是编译器自动进行的,对于程序员是不可见的),

C++将虚函数做成虚函数表,存储了多个虚函数的入口地址,然后将对应的虚函数指针放置到虚函数表中。

C++编译器不需要区分是子类对象还是父类对象,区分这个函数是虚函数还是普通函数,如果是普通函数就进行普通函数的调用(如果不是虚函数,那就表明是静态联编)。

父类对象中有一个vptr指针,子类中也有一个vptr指针,在确定一个函数是虚函数的时候,根据vptr指针找虚函数表,父类有个虚函数表,子类也有一个虚函数表,然后再找函数的入口地址,就实现了一个迟绑定的效果,也就是只有在运行的时候c++编译器采取判断。

构造函数中调用虚函数,能实现多态么?

vptr指针的分布初始化:

初始化子类的vptr指针是分布完成的。当直行父类的构造函数时(往往是先直行父类的构造函数在执行子类的构造函数),这个时候vptr指针指向的是父类的虚函数表,然后当直行子类的构造函数的时候,vptr指针指向的是子类的虚函数表,最后才完成vptr指针的初始化。

是否可将类函数中的每一个普通函数都声明为虚函数?可以,但是会影响到使用的效率不建议这么做。

通过虚函数表vptr确定调用的函数是在运行的时候直行的,因此需要通过寻址操作才可以找到真正应该调用的函数,而普通函数在编译阶段就可以确定要调用的函数,因此在效率上而言,虚函数需要寻址这一步,因此会慢一点。

说这么多,为的是说明C++编译器其实并没有区分是子类对象还是父类对象,而是通过vptr的形式进行区分的。

多态的理解

效果:同样一个调用语句,有不同的调用形态,

实现条件:继承,有virtual重写,有父类指针指向子类对象

多态实现的理论基础:动态联编和静态联编,根据实际对象类型来调用重写的函数。

多态的重要意义是设计模式的基础,是框架的基石。

函数指针做函数参数,多态的原理也是函数指针做函数参数,实现一个回调的效果。

多态的原理具体实现。

子类指针步长和父类指针步长是不同的概念

多态时用父类指针指向子类对象,和将父类指着进行++操作是两个不同的概念,++操作每次跳过的内存块大小是两个不同的概念。

纯虚函数和抽象类

纯虚函数是在一个基类中说明的虚函数,在基类中没有定义,要求任何继承的类多有自己的版本。纯虚函数为各个派生类定义了一个公共接口,

纯虚函数的类型 virtual 类型 函数名(参数列表)=0

一个具有纯虚函数的类成为抽象类(这个概念和java中的差不多)

纯虚函数只定义,没有函数体,就是为了让派生类来继承。

虚函数类是不能创建对象的,不过可以创建对象指针,这个就是多态啊。

抽象类不能作为返回类型,抽象类不能作为参数,不过可以声明抽象类的引用。

最根本的原因在于,抽象类不能进行实例化,不过由于C++编译器支持多态,因此,可以作为函数返回值或者是函数参数。

C++中多态

标签:效率   实现   rtu   nbsp   初始化   自动   替换   函数指针   虚函数   

原文地址:http://www.cnblogs.com/andyniu/p/7827339.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!