目录
一、什么是多态
二、静态连编
三、动态连编
四、代码示例
一、什么是多态
顾名思义多态就是多种形态的意思。
例如:去游乐场玩,儿童买票是半价,成年人买票是全价,老年人买票打七折。 对比类的话,这个买票就是一个类的一个方法(函数)。儿童,成年人,老年人即是对象,这些对象调用同一个买票函数得出来的不同的票价,这就是多态。
我们教材里面对多态性的描述是:不同对象收到相同的的消息时(即调用相同的函数),产生不同的动作。直观的说,多态性是指用一个名字定义不同的函数(这里只要函数名相同就行),这些函数执行不同但又类似的 *** 作,从而可以使用相同的方式来调用这些具有不同功能的同名函数。
在C++中,多态的实现和连编这一概念有关。所谓连编就是把函数名与函数体的程序代码连接在一起的过程。连编又分为静态连编和动态连编。(这里可以先看后面静态连编和动态连编的介绍)。
从实现的角度来说,多态可划分成两类:编译时的多态和运行时的多态。
编译时的多态是通过函数重载和运算符重载(重载采用的是静态连编)实现。(注意:函数重载实现的多态是一个类的行为的多态,要在同一个类内才能体现出来的多态,是面向方法的多态)。
运行时多态主要是通过虚函数(虚函数采用的是动态连编)来实现的。(注意:虚函数可以实现继承的多态也可以实现非继承的多态,是面向对象的多态)。
二、静态连编静态连编时,系统用实参与形参进行匹配,对于同名的重载函数变根据参数上的差异进行区分,然后进行连编,从而实现编译时的多态。(注意:函数的选择是基于指向对象的指针类型或者引用类型)
三、动态连编动态连编是运行阶段完成的连编。即当程序调用到某一函数的时候,系统会根据当前的对象类型去寻找和连接其程序的代码,对面向对象的程序而言,就是当对象收到某一消息的时候,才去寻找和连接相应的方法。(函数的选择是基于对象的类型)。
四、代码示例1.当没用使用虚函数时
#include
using namespace std;
class A{
public:
void show()
{
cout<<"我是A"<show();
pc=&b; //赋值兼容规则
pc->show();
}
运行结果:
我是A
我是A
这里有同学就会问了:pc指针后面不是指向了b对象吗?不应该是调用b对象的show函数吗?最后一句不应该是输出“我是B”吗?
都是输出“我是A”的原因是这些函数采用的都是静态连编,而静态连编选择函数是基于指向对象的指针类型,这里pc的类型是A,所以一直都是调用a对象的show函数。
那么怎么改才能实现不同的输出呢? 答案就是使用虚函数。
2.使用虚函数
#include
using namespace std;
class A{
public:
virtual void show()
{
cout<<"我是A"<show();
pc=&b; //赋值兼容规则
pc->show();
}
运行结果:
我是A
我是B
只需要在父类的show函数前面加一个virtual关键字就行了,加了之后show函数就会采用动态编译,只有到调用到它的时候,才去根据调用它的对象类型去匹配相应的函数体。
在以继承方式实现运行时多态的时候,子类的同名函数必须修改其函数体并且在函数的前面最好加上一个virtual关键字,因为通过继承的方式实现多态的时候,系统通过会根据一些规则自动识别出子类的虚函数。(ps:不通过继承关系也可以实现运行时多态,这时两个不同类的函数名都需要加上virtual才行,而且定义的指针指向其他对象时,要进行强制转换,下面举个例子给大家看一下。)
#include
#include
using namespace std;
class person{
public:
virtual int test()
{
string h="人";
cout<test();
dog d;
pr=(person*)&d; //两个完全不想关的类之间不能通过赋值兼容规则赋值了,要强制转换。
pr->test();
}
运行结果:
人
狗
。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)