多态与虚函数
1.多态性
多态的概念:
l 在面向对象的概念中,多态性是指不同对象收到相同消息时,根据对象类不同产生不同的动作。
C++允许程序员发送相同消息到不同的相关对象,而由对象决定如何完成该动作,并且支持软件选择实现决策的时间。其中,运行时的多态是面向对象的程序设计语言所独有的。有人还认为,只有与动态联编相结合的多态才是真正的面向对象的多态。
多态的特点:
l 提供了把接口与实现分开的另一种方法;
l 提高了代码的组织性和可读性,更重要的是它使软件的可扩充性有了充分的提高;
l 是OOP的一个重要特征,提供了丰富的逻辑关系清晰的描述对象方法的手段,提高了软件功能和版本进化的设计维护能力。
C++支持两种多态性:
l 编译时多态:程序运行前发生的事件——函数重载、运算符重载——静态绑定
l 运行时多态:程序运行时发生的事件——虚函数机制 ——动态绑定
2.函数绑定(function call binding)
绑定:将函数调用与函数体连接起来叫做绑定。
预绑定(early binding):绑定在程序运行之前进行(由编译器和连接器执行),也叫静态联编。
后绑定(late binding):编译器在编译时未确定要调用的函数,必须根据程序运行所产生的信息来通知调用哪一个函数,也叫动态联编。
C语言就只有一种绑定方式就是预绑定。
预绑定与后绑定的区别:
预绑定:
l 意味着绑定基于的信息都是静态的,是编译和连接时就可以确定的;
l 编译系统根据指针(或引用)本身的类型,而不是它所指向的对象的类型来进行绑定;
l 预绑定的实体包括一般函数、重载函数、非虚成员函数和非虚友元函数。
后绑定:
l 在运行时,根据对象类型的不同来选择合适的函数调用,这些类型信息在编译时是不可知的,故只能用后绑定解决这一问题;
l 拥有虚函数的类对象中,必然包含着相应的类型信息,否则动态绑定不可能实现;
l 编译时的多态的实现,取决于程序的静态信息是否足够为相同的程序实体确定不同的标识符。这里的程序实体,是指程序代码中的各种名称和代码段;
l 要实现运行时的多态,进行动态联编,就必须使用虚函数。
编译时的多态,表现在以下几方面:
l 对于在一个类中说明的重载,编译系统根据重载函数的参数个数、类型以及顺序的差别,来分别调用相应的函数;
l 对于在基类和派生类中重载函数,即使所带参数完全相同,由于它们属于不同的类,在编译时可以根据对象名前缀来加以区别;或者使用“类名::”前缀,也可以指示编译器分辨出应该调用哪个类的成员函数;
l 调用编译时绑定的函数,优点是高效率,因为编译系统可以在运行前对代码进行优化;缺点是缺少灵活性,不能满足程序的可扩充性要求。
例1:编写基类、派生类、子派生类,在基类中定义虚函数,并全部实现,定义每个类的对象,观察每种对象的大小及其内存分配规律。
代码如下:
/************************************************************************
* 虚函数彻底研究
************************************************************************/
#include <IOSTREAM.H>
//基类
class CBase
{
int x;
public:
CBase(int n) {x=n;}
~CBase(){}
virtual void SetX(int n) {x=n;}
virtual int GetX() {return x;}
};
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
//派生类
class CDerive : public CBase
{
int x;
public:
CDerive(int n1,int n2):CBase(n1)
{
x=n2;
}
~CDerive() {}
void SetX(int n) {x=n;}
int GetX() {return x;}
};
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
//子派生类
class CSubDerive : public CDerive
{
int x;
public:
CSubDerive(int n1,int n2,int n3):CDerive(n1,n2)
{
x=n3;
}
~CSubDerive() {}
void SetX(int n) {x=n;}
int GetX() {return x;}
};
void main()
{
cout<<"CBase size = "<<sizeof(CBase)<<endl;
cout<<"CDerive size = "<<sizeof(CDerive)<<endl;
cout<<"CSubDerive size = "<<sizeof(CSubDerive)<<endl;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
CBase obj1(1);
CDerive obj2(2,3);
CSubDerive obj3(4,5,6);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
CBase *pObj1=&obj1;
CDerive *pObj2=&obj2;
CSubDerive *pObj3=&obj3;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
CBase *pObj[]={pObj1,pObj2,pObj3};
}
1. 运行结果:
2. 对象的地址及内容:
可以看出,子派生类的前4个字节(低地址)是虚函数表的地址,接下来的4个字节是从基类继承来的x,然后是由派生类继承来的x,最后才是该类的x(高地址);派生类的对象空间也如此。
3. 基类指针指向三个对象时,指针的内容:
要虚函数发挥作用,必须用基类的指针(或引用)指向派生类的对象,并用指针(或引用)调用虚函数。也就是说,只有用地址才能体现运行多态性。因为不论是指向基类还是指向派生类的指针(引用),大小都是一样的,这样才能用基类指针指向派生类对象。这时,指针提供的信息是不完全的,在编译阶段不知道应该调用虚函数的哪个版本。而如果用对象调用虚函数,由于类型已经确定了,因此编译系统很可能采用预绑定;
分享到:
相关推荐
一、ERA5数据下载,deepseek提问全图
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
该项目是一款基于Spring Boot和VUE框架构建的校园闲置物品在线交易平台源码,总计包含732个文件,涵盖了丰富的资源类型,包括226个GIF图片、148个JavaScript文件、87个Java文件、64个HTML文件、46个JPG图片、42个CSS文件、28个PNG图片、16个XML文件、14个LESS和SCSS样式表文件。该平台的设计与开发旨在为校园内的学生提供一个便捷的闲置物品交流与交易环境。
停车位状态检测系统源码和数据集:改进yolo11-DCNV2-Dynamic
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
树莓派人脸识别(dlib,opencv自带的算法)
法国Embouchure地区沉积物岩性数据集 内容 该数据集由O. Puertas在2014年发布,详细记录了法国Embouchure地区的EMBOU岩芯沉积物的岩性特征。数据集中包含了39个数据点,提供了关于该地区沉积环境的重要信息。欲了解更多信息,请访问"PANGAEA数据库中的原始数据" ()。
使用android studio实现科大讯飞的aikit语音唤醒功能, 纯净版最新版语音唤醒功能
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
华为整理题
【GO】基于go实现的生日提醒定时任务_pgj
沉积物岩心KS03的岩石学数据 内容 这份数据集由Nelle, O在2014年发布,详细记录了沉积物岩心KS03的岩石学特征。数据集包含了15个数据点,提供了对特定地质样本的深入分析。欲了解更多信息,请访问"此处" ()以查看完整的数据集。
内容: 德国海洋研究中心(GEOMAR)的Christian Hensen于2014年发布的关于沉积物核心GeoB9040-1的孔隙水地球化学数据。该数据集包含了147个数据点,提供了详细的孔隙水成分分析结果。通过访问以下链接可获取完整的数据集信息:"" ()。此研究对于理解特定海洋沉积环境中的生物地球化学过程具有重要意义。
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
【前端】基于rasa的机器人的前端项目
C++ 进行AI图像超分的Demo,NuGet拉取OnnxRuntime和OpenCV环境即可运行。 注意:资源应该是免费下载的,如果需要积分或无法下载,请联系我。
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
震动传感器接线图