第18讲运算符重载 教学目的与要求: 了解运算符重载的作用。 掌握运算符重载的两种形式 教学内容提要: 、运算符重载的概述; 2、运算符重载为友元函数; 3、运算符重载为成员函数; 教学重点:运算符重载的两种形式。 教学难点:运算符重载的两种形式。 教学进度:P164P182 °教学过程:
第18讲 运算符重载 •教学目的与要求: 了解运算符重载的作用。 掌握运算符重载的两种形式。 •教学内容提要: 1、 运算符重载的概述; 2、运算符重载为友元函数; 3、运算符重载为成员函数; •教学重点:运算符重载的两种形式。 •教学难点:运算符重载的两种形式。 •教学进度:P164~P182 •教学过程:
18.1运算符重载概述 18.1.1什么是运算符重载 1、为什么要运算符重载? C艹中预定义的运算符操作对象只能是基本数据类型。实 际上,对于很多用户自定义类型(比如类),也需要有类似 的运算操作。这就提出了对运算符进行重新定义,赋予已有 符号以新的功能的要求。 2、运算符重载:是对已有的运算符赋予多重含义,同一个运 算符作用于不同类型的数据导致不同类型的行为 运算符重载的实质就是函数重载。在实现过程中,首先把指 定的运算表达式转化为对运算符函数的调用,运算对象转化 为运算符函数的实参,然后根据实参的类型来确定需要调用 的函数,这个过程是在编译过程中完成的。 注意:在C++中,运算符是系统定义的函数
18.1运算符重载概述 18.1.1 什么是运算符重载 1、为什么要运算符重载? C++中预定义的运算符操作对象只能是基本数据类型。实 际上,对于很多用户自定义类型(比如类),也需要有类似 的运算操作。这就提出了对运算符进行重新定义,赋予已有 符号以新的功能的要求。 2、运算符重载:是对已有的运算符赋予多重含义,同一个运 算符作用于不同类型的数据导致不同类型的行为。 运算符重载的实质就是函数重载。在实现过程中,首先把指 定的运算表达式转化为对运算符函数的调用,运算对象转化 为运算符函数的实参,然后根据实参的类型来确定需要调用 的函数,这个过程是在编译过程中完成的。 注意:在C++中,运算符是系统定义的函数
定义一个简化的复数类 complex: class complex i public: double real, imag; complex(double r=0, double i=0) i real=r; imag= 若要把类 complex的两个对象com1和c0m2加在一起,下面的 语句是不能实现的: maino complex com1(1. 1, 2.2), com2(3.3, 4.4), total total=coml+com2;∥错误 return 0
定义一个简化的复数类complex: class complex { public: double real,imag; complex(double r=0,double i=0) { real=r; imag=i;} }; 若要把类complex的两个对象com1和com2加在一起,下面的 语句是不能实现的: main() { complex com1(1.1,2.2),com2(3.3,4.4),total; total=com1+com2; //错误 //… return 0; }
若要将上述类 complex的两个对象相加,只要编写一个运算符函 数 operator.+O,如下所示: complex operator+(complex oml, complex om2) complex temp temp. reaF=oml. real+om2 real; temp. imag=oml imag+om2 imag; return temp; 我们就能方便地使用语句: total=com1+com2 将类 complex的两个对象com1和com2相加
若要将上述类complex的两个对象相加,只要编写一个运算符函 数operator+(),如下所示: complex operator+(complex om1,complex om2) { complex temp; temp.real=om1.real+om2.real; temp.imag=om1.imag+om2.imag; return temp; } 我们就能方便地使用语句: total=com1+com2; 将类complex的两个对象com1和com2相加
18.1.2运算符重载的规则 1、C+中的运算符除了少数几个外,全部可以重载,而且只能重 载已有的这些运算符。不能被重载的运算符:“*”,“::”, sizeof DaD 2、重载之后运算符的操作数个数、优先级和结合性不能改变。 3、用于类的对象的运算符必须重载,但是有两种例外情形: ①赋值运算符(=)无需重载就可以用于每一个类。在不 提供重载的赋值运算符时,赋值运算符的默认行为是逐个拷贝 类的数据成员。 ②地址运算符&也无需重载就可以用于任何类的对象, 它返回对象在内存中的地址。当然地址运算符也可以被重载 4、在重载运算符()、[]、→>或者=时,运算符重载必须声明 为类的一个成员。对于其它的运算符,运算符重载函数可以是友元 5、C十+语言中只能重载原先已有定义的运算符
18.1.2 运算符重载的规则 1、C++中的运算符除了少数几个外,全部可以重载,而且只能重 载已有的这些运算符。不能被重载的运算符:“*” , “ :: ” , “?: ” ,“sizeof”,“.” 。 2、重载之后运算符的操作数个数、优先级和结合性不能改变。 3、用于类的对象的运算符必须重载,但是有两种例外情形: ① 赋值运算符(=)无需重载就可以用于每一个类。在不 提供重载的赋值运算符时,赋值运算符的默认行为是逐个拷贝 类的数据成员。 ② 地址运算符& 也无需重载就可以用于任何类的对象, 它返回对象在内存中的地址。当然地址运算符也可以被重载。 4、在重载运算符( )、[ ]、–> 或者 = 时,运算符重载必须声明 为类的一个成员。对于其它的运算符,运算符重载函数可以是友元。 5、C++语言中只能重载原先已有定义的运算符
18.2运算符重载的两种形式 18.2.1友元运算符函数 1.友元运算符函数定义的语法形式 友元运算符函数的原型在类的内部声明格式如下: class X friend返回类型 operator运算符(形参表); 在类外定义友元运算符函数的格式如下: 返回类型 operator运算符(形参表) 函数体
18.2运算符重载的两种形式 18.2.1 友元运算符函数 1. 友元运算符函数定义的语法形式 友元运算符函数的原型在类的内部声明格式如下: class X { //… friend 返回类型 operator 运算符(形参表); //… } 在类外定义友元运算符函数的格式如下: 返回类型 operator 运算符(形参表) { 函数体 }
说明:参数表的参数个数 个参数单目运算符 个参数双目运算符 2.双目运算符重载 当用友元函数重载双目运算符时,两个操作数都要传 递给运算符函数。 调用形式: 般而言,如果在类X中采用友元函数重载双目运算符a, 而aa和b是类X的两个对象,则以下两种函数调用方法 是等价的: aa(a bb ∥隐式调用 operator (a(a,bb);∥显式调用
说明:参数表的参数个数 一个参数 单目运算符 二个参数 双目运算符 2. 双目运算符重载 当用友元函数重载双目运算符时,两个操作数都要传 递给运算符函数。 调用形式: 一般而言,如果在类X中采用友元函数重载双目运算符@, 而aa和bb是类X的两个对象,则以下两种函数调用方法 是等价的: aa @ bb; // 隐式调用 operator @(aa,bb); // 显式调用
例181复数类加减法运算符重载友元函数形式 class complex i double real, imag public: complex(double r=0, double i=0) i real=r; imag=rs friend complex operator + complex cl, complex c2); friend complex operator-( complex cl, complex c2); void printo; complex operator +(complex cl, complex c2) i complex c; c rea=cl real+c2 real: cimag=climag+c2 imag; return c
例18.1 复数类加减法运算符重载——友元函数形式 class complex { double real,imag; public: complex(double r=0,double i=0) { real=r; imag=r;} friend complex operator +( complex c1,complex c2); friend complex operator -( complex c1,complex c2); void print(); }; complex operator +(complex c1,complex c2) { complex c; c.real=c1.real+c2.real; c.imag=c1.imag+c2.imag; return c; }
complex operator -(complex cl, complex c2) i complex c, c rea=cl. real-c2 real: coImag=clic3=cl+c2相当于c3- operator+(cl,c2) return c, c3=c1-c2相当于c3= operator-(c1,c2) vOid comple cout"=C1+c2=>, c3 printo) c3=c1-c2; cout<<”c3=c1-c2=”;c3. print(
complex operator - (complex c1,complex c2) { complex c; c.real=c1.real-c2.real; c.imag=c1.imag-c2.imag; return c; } c3=c1+c2 相当于 c3=operator+(c1,c2); c3=c1-c2 相当于 c3=operator-(c1,c2);
3.单目运算符重载 用友元函数重载单目运算符时,需要 个显式的操作数 调用形式: 般而言如果在类X中采用友元函数重载单 目运算符@,而a是类X的对象,则以下两 种函数调用方法是等价的: aaa ∥隐式调用 operator @aa); 显式调用 例182:见教材例54用友元函数重载单目 运算符
3. 单目运算符重载 用友元函数重载单目运算符时,需要 一个显式的操作数。 调用形式: 一般而言,如果在类X中采用友元函数重载单 目运算符@,而aa是类X的对象,则以下两 种函数调用方法是等价的: @aa; // 隐式调用 operator@(aa); // 显式调用 例18.2 :见教材例5.4 用友元函数重载单目 运算符“-”