面向对象程序设计-多态性
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
friend complex operator * (complex c);
friend complex operator / (complex c);
};
3 单目运算符重载
对单目运算符而言,成员运算符函数的参 数表中没有参数,此时当前对象作为运算 符的一个操作数。
详见P179 例5.8
由于所有的成员函数都有一个this指针,因 此任何对对象私有数据的修改都将影响实 际调用运算符函数的对象。
同的目标代码块(OBJ等),这些代码 和库要进行连接形成最终代码(EXE等) 目标代码中函数调用处含有连接信息
连接信息含有被调用函数的地址,若地 址固定就成为静态地址值;若地址不固 定就是指针变量(函数指针)
2 多态性的实现原理(续)
图例说明多态的实现
main { int n; short age; //…
一般格式:
class X{ //……
返回类型 operator 运算符(参数表)
//…… }; 返回类型 X::operator 运算符(参数表) {
函数体 } 单目运算符,参数表为空;双目为一个操作数。
2 双目运算符重载
#include <iostream.h>
具体实现见例5.7
class complex {
Add(实参);
main函数 代码在{}中 代码前半部分
Add函数调用
Add代码1 Add代码2
//… return 0;
};
代码后半部分
连接信息所在
Add代码3
2 多态性的实现原理(续)
编译后连接信息中函数地址值固定不变, 在此基础上实现的多态称为静态多态
C++中,静态多态表现为函数重载和运算 符重载(特殊的函数重载)
};
3 成员运算符重载(续)
complex complex ::operator+(complex c) { complex temp;
temp.real=real+c.real; temp.imag=this->imag+c.imag; return temp; }
void main() { complex c1(1.0,2.0),c2(3.0,4.0),t;
绑定过程在程序运行时执行,在程序运行 时才确定将要调用的函数(指针指向)。
§5.2. 函数重载
1 普通函数重载
函数名相同,但返回类型、参数类型和顺 序不尽相同的现象
普通函数重载
void Add(int) { //…… } void Add(char) { //…… } void Add(short)
成员函数因为含有类的this指针参数,所 以自然就可以相互区分开
2 类的成员函数重载(续)
继承中函数重载示例
class point{
class circle:public point{
int x,y; public:
point(int a,int b) { x=a; y=b; }
float area() { return 0.0; } };
第5章 多态性
内容提要
1 多态性的概念 1)多态性的概念 2)多态性的实现原理* 3)静态绑定与动态绑定
2 函数重载 1)普通函数重载 2)类的成员函数重载 3)名字修饰
内容提要(续)
3 运算符重载 1)运算符重载 2)一般运算符函数(友元) 3)成员运算符重载 4)调用方式 5)运算符重载使用说明
int r; public:
circle(int a,int b,int c) :point(a, b)
{ r=c; } float area() { return 3.14*r*r; } };
3 名字修饰
C++编译器对函数进行编译时,使用名 字修饰技术,对函数处理后形成内部名
名字修饰技术把函数名和参数类型综合起 来,形成内部名称(目标代码中)
§5.3.4
成员运算符函数与友 员运算符函数的比较
比较
参数个数不同
双目运算符一般重载为友员或成员运算符 函数,但有一种情况,必须使用友员函数
在5.4的类AB中,用成员重载“+”运算符:
AB::operator + (int x){ AB temp; temp.a = a + x; Temp.b = b + x;
编译系统对重载运算符的选择,遵循函数 重载的选择原则(参数类型匹配)
1 运算符重载(续)
可以重载的运算符 单目: - + ! ~ ++ -- 等 双目: + - * / % < > << >> 等 其他:[] -> () = += new delete等
不可以重载的运算符: . * :: ?: sizeof(5个)
t=c1+c2; // operator+(c1,c2); }
3 成员运算符重载
运算符重载目的是为了满足新类型(类) 的运算需要
根据封装和隐藏原理的要求,类中的数据 成员一般为私有,所以大部分的一般运算 符都重载为友元运算符
另外一种重载方法是把运算符放在类中, 成为成员运算符
3 成员运算符重载(续)
{ //…… }
调用Add的函数 代码
代码前半部分
Add(int)
Add(5)函数调用 (函数的地址)
代码后半部分
Add(char) Add(short)
2 类的成员函数重载
成员函数的重载有两种情况: 1)一种是参数有所差别的重载,这和普 通函数的重载规则一样 2)另一种是函数所带的参数完全相同, 但要求他们属于不同的类(或名字空间), 特别是在类的继承关系中
比如(相似的理解):
int Add(int); void Add(int, char);
Add_INT Add_INT_CHAR
§5.3. 运算符重载
1 运算符重载Байду номын сангаас
实质:一种特殊的函数重载 作用:扩展了C++的类型机制 分为一般运算符重载和类成员运算符重载 一般格式:
返回类型 operator 运算符名(参数表) {
};
2 一般运算符重载示例(续)
complex operator+(complex o1, complex o2) { complex temp;
temp.real=o1.real+o2.real; temp.imag=o1.imag+o2.imag; return temp; }
void main() { complex c1(1.0,2.0),c2(3.0,4.0),t;
编译后连接信息中函数地址值用指针指向, 在此基础上实现的多态称为动态多态
C++中,动态多态是通过虚函数实现的
3 静态绑定与动态绑定
绑定
程序中的操作(函数)调用与执行该操作 的代码关联过程称为绑定。
静态绑定(编译时)
绑定过程出现在编译阶段,用对象名或者 类名来限定要调用的函数。
动态绑定(运行时)
}
执行效率要高
3 单目运算符重载
用友员函数重载单目运算符时,需要一个 显式的操作数。 例5.4
需要注意的是:使用友员函数重载“++”、 “--”这样的运算符,可能会出现一些问题。 例5.5 临时对象不能实现。 例5.6 采用引用参数传递可实现。
§5.3.3 成员运算符函数
1 定义的语法形式
内容提要(续)
4 虚函数* 1)虚函数的概念 2)虚函数的定义和使用 3)继承中的虚函数* 4)纯虚函数和抽象类*
§5.1. 多态性的概念
1 多态性的概念
多态性是面向对象系统的重要特征之一 多态性——指发出同样的消息被不同类型
的对象接收时有不同的行为的现象 多态提高了软件的可重用性和可扩充性
private:
double real;
double imag;
public:
complex(double r = 0.0, double i = 0.0);
void print();
friend complex operator + (complex c);
friend complex operator - (complex c);
t=c1+c2; // c1.operator+(c2); }
4 调用方式
调用方式
可以象C运算符的使用: complex a,b,c; c=a+b;
也可以象函数那样使用: c=operator+(a,b); c=a.operator+(b); 或者 c.operator=(a.operator(b));
2 一般运算符重载示例
class complex{ double real; double imag;
public: complex(double r=0.0,double i=0.0) { real=r; imag=i; } double getReal() { return real; } double getImag() { return imag; } friend complex operator+(complex, complex);
1 多态性的概念(续)
C++中,多态表现为一个名字定义不同的 函数,这些函数执行不同但相似的操作, 即用同样的接口访问功能不同的函数,从 而可以实现“一个接口,多种方法”
C++多态的实现: 函数重载 运算符重载 虚函数
2 多态性的实现原理
多态性实现和编译连接、执行密切相关 C++源程序中函数的经过编译后形成不
复数类的运算符重载
#include <iostream.h> class complex {
private: double real; double imag;
public: complex(double r = 0.0, double i = 0.0); void print(); friend complex operator+(complex a, complex b); friend complex operator-(complex a, complex b); friend complex operator*(complex a, complex b); friend complex operator/(complex a, complex b);
示例
class complex{ double real; double imag;
public: complex(double r=0.0,double i=0.0) { real=r; imag=i; } double getReal() { return real; } double getImag() { return imag; } complex operator+(complex);
//…… } 其中operator是关键词,“operator运算符” 相当于函数名
1 运算符重载(续)
运算符重载是对已有运算符赋予多重含义 必要性
预定义运算符其运算对象只能是基本数据 类型,而不适用于用户自定义类型(如类)
实现机制
运算表达式将转化为对运算符函数的调用, 运算对象转化为运算符函数的实参
1 定义的语法形式
一般格式:
class X{ //……
friend返回类型 operator 运算符(参数表)
//…… }; 返回类型 operator 运算符(参数表) {
函数体 }
2 双目运算符重载
两个复数a+bi和c+di进行加、减、乘、除 的方法如下:
加法: (a+bi) +(c+di)=(a+c) + (b+d)i 减法: (a+bi) - (c+di)=(a-c) + (b-d)i 乘法: (a+bi) * (c+di)=(ac+bd)+(ad+bc)i 除法: (a+bi)/(c+di)=[(a+bi)*(c-di)]/(c2-d2)
};
说明:
如果类X中采用友员函数重载双目运算符@,而 aa和bb是类X的两个对象,则以下两种函数调用 方法是等价的:
aa @bb; operator @(aa, bb);
函数返回说明:
//隐式调用 //显示调用
complex operator+(complex a, complex b)
{
return complex(a.real+b.real, a.imag+b.imag);
5 运算符重载使用说明
只能对已有运算符重载,不能造新算符, 并且重载的运算符与原有功能相似
不能改变运算符目数、优先级和结合性 成员运算符重载比一般运算符(友元)重
载的参数数目少一个 有一种情况必须使用友元运算符重载,如:
complex t=complex(2,3)+c1;
§5.3.2 友员运算符函数