关键词不能为空

当前您在: 主页 > 英语 >

C++中的多态

作者:高考题库网
来源:https://www.bjmy2z.cn/gaokao
2021-03-03 12:44
tags:

-

2021年3月3日发(作者:耳饰)


1.


什么是多态



多 态是


C++


中的一个重要的基础,可以这样说,不掌握多态就是


C++


的门个


汉。我就给它定一个这样 的名字


--


“调用’同名函数’却会因上下文不同会有


不同的实现的一种机制”


。这个名字长是长了点儿,可是比“多态”清 楚多了。


看这个长的定义,


我们可以从中找出多态的三个重要的 部分。


一是


“相同函数名”



二是“依据上下文”


,三是“实现却不同”


。我 们且把它们叫做多态三要素吧。



2.


多态带来的好处



多态带来两个明显的 好处:


一是不用记大量的函数名了,


二是它会依据调用


时的上下文来确定实现。确定实现的过程由


C++


本身完成,另外还有一个不明显


但却很重要的好处是:带来了面向对象的编程。



3. C++


中实现多态的方式



C++


中共有三种实现多态的方式。由“容易说明白”到“不容易说明白”排


序分别为


:


第一种是函数重载;第二种是模板函数;第三种是虚函数。



4.


细说用函数重载实现的多态


< /p>


函数重载是这样一种机制:允许有不同参数的函数有相同的名字。



具体一点讲就是:假如有如下三个函数:



void test(int arg){} //


函数


1


void test(char arg){} //


函数


2


void test(int arg1,int arg2){} //


函数


3


如果在

< br>C


中编译,将会得到一个名字冲突的错误而不能编译通过。在

C++



这样做是合法的。


可是当 我们调用


test


的时候到底是会调用上面三个函数中的哪


一个呢?这要依据你在调用时给的出的参数来决定。如下:



test(5); //


调用函数


1


test('c');//


调用函数


2


test(4,5); //


调用函数


3


C++


是如何做到这一点的呢?原来聪明的


C++


编译器在 编译的时候悄悄的在


我们的函数名上根据函数的参数的不同做了一些不同的记号。具体说 如下:



void test(int arg) //


被标记为‘


test


有一个

< br>int


型参数’



void test(char arg) //


被标记为‘


test


有一个


char


型的参数’



void test(int arg1,int arg2) //


被标记为



test


第一个参数是


int


型,


第二个参数< /p>



int


型’



这样一来当我们进行对


test


的调用 时,


C++


就可以根据调用时的参数来确定

到底该用哪一个


test


函数了。噢,聪明的


C++


编译器。其实


C++


做标记做的比我


上面所做的更聪明。我上面哪样的标记太长了。


C++


编译器用的标记要比我的短


小的多。看看这个真正的


C++


的对这三个函数的标记:



?test@@YAXD@Z


?test@@YAXH@Z


?test@@YAXHH@Z


是不是短多了。


但却不好看明白了。


好在这是给计算机看的,


人看不 大明白


是可以理解的。



还记得


cout


吧。我们用


<<

可以让它把任意类型的数据输出。比如可以象下


面那样:



cout << 1; //


输出


in t




cout << 8.9; / /


输出


double




cout << 'a'; //


输出


char




cout <<


输出


char


数组型

< p>


cout << endl; //


输出一个函数



cout


之所以能够用一个函数名


<<



<<


是一个函数名)


就能做到这些全是函数

< p>
重载的功能。要是没有函数重载,我们也许会这样使用


cout

< p>
,如下:



cout int<< 1; //< /p>


输出


int




cout double<< 8.9; //


输出

< p>
double




cout char<< 'a'; //


输出


char




cout charArray<<


输出


char


数组型



cout function(


?


)<< endl; //


输出函数



为每一种要输出的类型起一个函数名,这岂不是很麻烦呀。


< /p>


不过函数重载有一个美中不足之处就是不能为返回值不同的函数进行重载。


那是因为人们常常不为函数调用指出返回值。


并不是技术上不能通过返回值来进


行重载。



5.


细说用模板函数实现的多态



所谓模板 函数(也有人叫函数模板)是这样一个概念:函数的内容有了,但


函数的参数类型却是待 定的(注意:参数个数不是待定的)


。比如说一个


(

< p>
准确的


说是一类或一群


)


函数带有两个参数,它的功能是返回其中的大值。这样的函数


用模板函数来实现是适合不 过的了。如下。



template < typename T>


T getMax(T arg1, T arg2)


{


return arg1 > arg2 ? arg1:arg2; //


代码段


1


}


这就是基于模板的多态吗?不是。因为现在我们不论是调用


getMax(1,


2)



是调用


getMax(3.0, 5.0)


都是 走的上面的函数定义。


它没有根据调用时的上下文不


同而执行不 同的实现。所以这充其量也就是用了一个模板函数,和多态不沾边。


怎样才能和多态沾上 边呢?用模板特化呀!象这样:



template<>


char* getMax(char* arg1, char* arg2)


{


return (strcmp(arg1, arg2) > 0)?arg1:arg2;//


代码段


2


}


这样一来当我们调用


getMax (



abc



,



efg



)


的时候,就会执行代码段


2



而不是代码段


1


。这样就是多态了。



更有意思的是如果我们再写这样一个函数:



char getMax(char arg1, char arg2)


{


return arg1>arg2?arg1:arg2; //


代码段


3


}


当我们调用


getMax(



a



,



b



)


的时候,执行的会是代码段


3


,而不是代

< p>
码段


1


或代码段


2



C++


允许对模板函数进行函数重载,就象 这个模板函数是一


个普通的函数一样。


于是我们马上能想到写下 面这样一个函数来做三个数中取大


值的处理:



int getMax( int arg1, int arg2, int arg3)


{


return getMax(arg1, max(arg2, arg3) ); //


代码段


4


}


同样我们还可以这样写:



template


T getMax(T arg1, T arg2, T arg3)


{


return getMax(arg1, getMax(arg2, arg3) ); //


代码段


5


}

< p>
现在看到结合了模板的多态的威力了吧。比只用函数重载厉害多了。



6.


小结



上面的两种多态在


C++


中有一个总称:静态多态。之所以叫它 们静态多态是


因为它们的多态是在编译期间就确定了。


也就是说 前面所说的函数


1



2



3


代码


< br>1




2



3



4



5


这些,在编译完成后,应该在什么样的上下文的调用中执行< /p>


哪一些就确定了。比如:如果调用


getMax(0.1, 0.2, 0.3)


就会执行代码段


5


。如果


调用


test(5)


就执行函数


1


。这些是在编译期间就能确定下来的。



静态多态还有一个特点,就是:


“总和参数较劲儿”




下面所要讲的一种多态就是必需是在程序 的执行过程中才能确定要真正执


行的函数。所以这种多态在


C+ +


中也被叫做动态多态。



7.


细说用虚函数实现的多态



7.1.


虚函数是怎么回事



首先来说一说虚函数,


所谓虚函数是这样一个概念:

基类中有这么一些函数,


这些函数允许在派生类中其实现可以和基类的不一样。在< /p>


C++


中用关键字


virtual


来表示一个函数是虚函数。



C++


中还有一个术语“覆盖”与虚函数关系密切。所谓覆盖就是说,派生类


中 的一个函数的声明,与基类中某一个函数的声明一模一样


,


包括 返回值,函数


名,参数个数,参数类型,参数次序都不能有差异。


(注


1


)说覆盖和虚函数关

-


-


-


-


-


-


-


-



本文更新与2021-03-03 12:44,由作者提供,不代表本网站立场,转载请注明出处:https://www.bjmy2z.cn/gaokao/700014.html

C++中的多态的相关文章