第五章多态性

第5章  多态性

一、编译时的多态性和运行时的多态性

多态性是指用一个名字定义不同的函数,这些函数执行不同但又类似的操作,这样就可以用同一个函数名调用不同内容的函数。 也是指不同的对象收到相同的的消息时, 执行不同的操作

多态性包括编译时的多态性运行时的多态性

(1)编译时的多态性:静态联编支持的多态性称为编译时的多态性,也称静态多态性。

静态联编----静态联编是指系统在[编译时]就决定如何实现某一动作。静态联编要求在程序编译时就知道调用函数的全部信息。通过函数重载(运算符重载)和模板

 补充:static是静态变量,就是变量值不随函数执行结束而消失,下次调用同一函数时,上次所赋予的值仍存在。const是常量,是不可改变的。

(2)运行时的多态性:动态联编所支持的多态性称为运行时多态性,也称动态多态性。

动态联编----动态联编是指系统在运行时动态实现某一动作。一直要到[程序运行时]才能确定调用哪个函数。通过虚函数

补充:程序是【先自上而下编译再是运行】 


二、运算符函数

1、 在类外定义的运算符重载函数

运算符函数:用于完成“+” “-” “*” “/” 等操作的函数

运算符函数名:operator@(@指要重载的运算符),例如operator+,operator-,operator*

运算符重载:两个或两个以上的运算符函数共有同一个运算符函数名


(重载分为一般函数重载和运算符重载)

补充:函数的重载的规则:  1、函数名称必须相同。 2、参数列表必须不同(个数不同、类型不同、参数排列顺序不同等)。 3、函数的返回类型可以相同也可以不相同。 4、仅仅返回类型不同不足以成为函数的重载。


引发的问题:C++系统预先编好的运算符函数不能完成将两个对象的相加工作。

解决方法如下:调用运算符函数将两个对象相加

complex operator+(complexco1,complex co2) {

    complex temp;

    temp.real=co1.real+co2.real;

    temp.imag=co1.imag+co2.imag;

    return temp;

}

[调用]运算符函数operator+()的有2种方式:

第一种:total1=operator+(com1,com2);//显示调用

第二种:total2=com1+com2;//隐式(习惯)调用


注意:C++语言对运算符重载制定了以下一些规则:【重点】

(1)以下运算符不能重载. 成员访问运算符  .* 成员指针访问运算符  ::作用域运算符 sizeof 长度运算符 ?:条件运算符

(2)不允许用户自己定义新的运算符进行重载

(3)最好保持运算符原含义,容易被人接受

(4) 重载不能改变运算符的操作对象(即操作数)的个数

(5) 重载不能改变运算符原有的优先级

例如,先乘除,后加减,因此表达式:x=y-a*b;等价于  x=y-(a*b);

 (5) 重载不能改变运算符原有的结合特性

例如:乘、除法运算符“*”和“/”都是左结合的

 (6) 运算符重载函数的参数至少应有一个类对象(或类对象的引用)

    例如以下定义运算符重载函数的方法是错误的:

       int operate+(int x,int y)【标准运算符】

       { return x+y;}

 (7)赋值运算符“=”,不必类对象用户进行重载


引发问题:运算符函数只能访问公有数据成员,而【不能访问类的私有数据成员】问题

解决方法:定义为它将要操作的类的成员函数(简称为成员运算符重载函数);

                   或者定义为它将要操作的类的友元函数(简称为友元运算符重载函数)

2、友元运算符重载函数定义:

(1)在类的内部定义友元函数格式为:

(2)在类中声明友元函数的原型,在类外定义

 friend complex operator+(complex co1,complex co2);

complex operator+(complex co1,complex co2)

补充:其他函数可以按照先声明后使用的方式,在main函数前先加一句声明;也可以直接调用,把函数放在main函数前。


注:在友元运算符重载函数的形参表中

若重载的是双目运算符,则参数表中有两个操作;+ *

若重载的是单目运算符,则参数表中只有一个操作。- & ! ++


说明:

(1)在函数返回的时候,可以直接用类的构造函数来生成一个临时对象,而不对该对象进行命名

Complex operator +(Complex& a,Complex& b){

         return Complex(a.real+b.real, a.imag+b.imag); 

        //临时也是无名对象,返回临时对象

}

引发的问题:使用友元函数重载“++”、“--”单目运算符,可能出现一些问题,会导致对形参的修改无法传到函数体外,于是要采用传址调用,把对象的引用作为参数。

friend coord operator ++(coord& op);    // 正确

friend complex operator +(complex a,complex b)//正确

引起错误的原因是在于友元函数没有this指针,所以不能引用this指针所指的对象。若函数采用对象参数,通过传值的方法传递参数,函数体内对op的所有修改都无法传道函数体外。 

说明:

(1)运算符重载函数operator @可以返回任何类型,甚至可以是void类型,但通常返回类型与它所操作的类的类型相同,这样可以使重载运算符用在复杂的表达式中。

(2) 有的运算符不能定义为友元运算符重载函数,如赋值运算符=、下标运算符[]、函数调用运算符()等。


3.成员运算符重载函数【成员运算符函数的参数跟友元运算符函数不一样,比友元运算符函数少一个参数】

(1)在类的内部,定义成员运算符重载函数

(2)在类的内部, 声明成员运算符重载函数原型的格式如下:


注:在成员运算符重载函数的形参表中

若运算符是单目的,则参数表为空;

若运算符是双目的,则参数表中有一个操作数----右操作数,当前对象----左操作数,它是通过this指针隐含地传递给函数的。


4.成员运算符重载函数与友元运算符重载函数的比较【重点】

1. 对双目运算符而言,成员运算符重载函数带有一个参数,而友元运算符重载函数带有两个参数;对单目运算符而言,成员运算符重载函数不带参数,而友元运算符重载函数带一个参数。

2. 双目运算符一般可以被重载为友元运算符函数或成员运算符函数

  [  但有一种情况,必须使用友元函数。]

引发问题:上例中整数50不能调用成员运算符函数

解决方法:使用两个友元函数

                  friend nclass operator+(nclass ob,int x);

                  friend nclass operator+(int x,nclass ob);

一般而言:

·对于单目运算符++,建议选择成员函数;

·对于运算符“=、()、[]、->”只能作为成员函数;

·对于运算符“+=、-=、/=、*=、&=、!= 、~=、%=、<<=、>>=”,建议重载为成员函数;

·对于其他运算符,建议重载为友元函数。


5. + +和- -的重载

对于前缀方式 ++ob

1. 成员运算符函数为:ob.operator ++( );

2. 友元运算符函数为: operator ++(X& ob);//ob为类X对象的引用

对于后缀方式 ob++

1. 成员运算符函数为:ob.operator ++(int);// 增加一个参数int,表示与后缀方式

2. 友元运算符函数为: operator++(X &ob,int);// 调用时,参数int一般被传递给值0


6.  赋值运算符=的重载

调用默认的赋值运算符函数,将对象obj2的数据内容逐域拷贝到对象obj1中。


三、类型转换

1、两种类型转换方式

隐式转换:小化大

显示转化

2、转换构造函数也是一种构造函数,它只有一个参数,作用是将一个其他类型的数据转换成它所在类的对象【与构造函数要区别开来】

3、类型转换函数,作用是将一个类的对象转换成另一个类型的数据

说明:

1.类型转换函数只能定义为一个类的成员函数而不是定义为友元函数

2.没有参数,也没有在函数面前指定类型

3.必须有return

4.一个类可以有多个类型转换函数


五、虚函数

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,752评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,100评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,244评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,099评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,210评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,307评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,346评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,133评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,546评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,849评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,019评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,702评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,331评论 3 319
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,030评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,260评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,871评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,898评论 2 351

推荐阅读更多精彩内容