第四章_运算符重载


#include <iostream.h> class Complex {public: Complex () {real=0;imag=0;} Complex (double r) {real=r;imag=0;} Complex (double r,double i) {real=r;imag=i;} friend Complex operator+ (Complex &c1, Complex &c2); void display(); private: double real; double imag; };
为了实现加法的交换率,必须定义两个运算符 重载函数,记住成员函数要求运算符左侧的操 作数必须是自定义类型的对象,而友元函数没 有这个限制,可以用下面两个组合中任意一个: (1)成员函数(左操作数是对象,右操作数 是非对象)、友元函数(左操作数是非对象, 右操作数是对象) (2)友元函数(左操作数是对象,右操作数 是非对象)、友元函数(左操作数是非对象, 右操作数是对象)
由于使用友元会破坏类的封装,要尽量将运算 符重载函数定义为成员函数。但考虑到各方面 的因素,一般将单目运算符重载为成员函数, 将双目运算符重载为友元函数。 VC++6.0的不带后缀h的头文件不支持把成员 函数重载为友元函数。但VC++6.0带后缀h的 头文件支持这项功能,所以要将程序中的语句: #include <iostream> using namespace std; 改成: #include <iostream.h> 即可正常运行。
运算符函数



声明形式 函数类型 operator 运算符(形参) { ...... } 重载为类成员函数时 参数个数=原操作数个数-1 (后置++、-除外) 重载为友元函数时 参数个数=原操作数个数, 且至少应该有一个自定义类型的形参。
不能重载的运算符只有5个: . 成员运算符 .* 成员指针运算符 :: 域运算符 sizeof 长度运算符 ?: 条件运算符 重载函数名是由operator和运算符联合组成。 复数加法运算符重载函数原型可以是: Complex operator+ (Complex &c2); 例4.2 重载运算符+,用于两个复数相加。
Complex Complex::operator + (Complex &c2) { Complex c; c.real=real+c2.real; c.imag=imag+c2.imag; return c; } void Complex::display() { cout<<"("<<real<<","<<imag<<"i)"<<endl; }
如果要求在使用重载运算符时,运算符左侧操 作数不是对象,就不能使用前面定义的运算符 重载函数,可以将运算符重载函数定义为友元 函数: friend Complex operator + ( int & i , Complex &c) { return Complex( c.real + i , c.imag ) ; } 友元函数不要求第一个参数必须是类类型,但 是要求实参要与形参一一对应: c3 = n + c2 // 顺序正确 c3 = c2 +n // 顺序错误
分析:定义一个复数类,用成员函数实 现加号的重载函数。两个复数相加结果 仍是复数,所以函数的返回值的类型也 是复数类。用成员函数实现运算符重载 函数时,调用格式是“对象名.成员名”, 此时对象就是一个参与运算的操作数, 加法还需要另一个操作数,这个操作数 用函数的参数传递,参数的类型就是复 数类。而运算结果用函数值返回。
请考虑在例4.2中能否用一个常量和一个复数 相加?如 c3 = 3 + c2; // 错误 应该定义对象:Complex C1(3.0,0) : c3 = C1 + c2; 注意:运算符重载后,其原来的功能仍然保留, 编译系统根据运算表达式的上下文决定是否调 用运算符重载函数。 运算符重载和类结合起来,可以在C++ 中定义 使用方便的新数据类型。
int main() {Complex c1(3,4),c2(5,-10),c3; c3=c1+c2; cout<<"c1=";c1.display(); cout<<"c2=";c2.display(); cout<<"c1+c2=";c3.display(); return 0; }
说明: (1)用运算符重载函数取代了例 4.1中的加 法成员函数,从外观上看函数体和函数返回值 都是相同的。 (2)在主函数中的表达式c3=c2+c1 取代了例 4.1中的c3=plex_add(c2) ,编译系统 将表达式c3=c1+c2 解释为 c1.operator + ( c2 ) 对象c1调用的重载函数operator + ,以c2为实 参计算两个复数之和。
4.5重载双目运算符
Complex operator+ (Complex &c1, Complex &c2) { return Complex(c1.real+c2.real, c1.imag+c2.imag) ; } // 显式调用构造函 数
void Complex::display() {cout<<"("<<real<<","<<imag<<"i)"<<en dl;}
运算符重载的实质




运算符重载是对已有的运算符赋予多重含义。 必要性 C++中预定义的运算符其运算对象只能是基本 数据类型,而不适用于用户自定义类型(如类) 实现机制 将指定的运算表达式转化为对运算符函数的调 用,运算对象转化为运算符函数的实参。 编译系统对重载运算符的选择,遵循函数重载 的选择原则。
int main() { Complex c1(3,4),c2(5,-10),c3; c3=c1+c2; cout<<"c1="; c1.display(); cout<<"c2="; c2.display(); cout<<"c1+c2="; c3.display(); return 0; }
加法运算符重载为友元函数,C++ 在编译时将 表达式c1+c2解释为 operator + ( c1, c2) 即相当于执行以下函数 Complex operator + ( Complex & c1, Complex & c2 ) { return Complex( c1.real + c2.real , c1.imag + c2.imag ) ; } 因为普通函数是不能直接访ห้องสมุดไป่ตู้对象的私有成员, 如果普通函数必须访问对象的私有成员,可调 用类的公有成员函数访问对象的私有成员。这 会降低效率。
在Complex类中定义了complex_add函数做 加法,函数的参数是引用对象,作为一个加数。 在函数里定义了临时对象c,两个赋值语句相 当于: c.real = this->real +c2.real; c.imag = this->imag+c2.imag; 在main函数中通过对象c1调用加法函数,上面 的语句相当于: c.real = c1.real +c2.real; c.imag = c1.imag+c2.imag; 能否用+运算符实现复数加法?
第四章 运算符重载
4.1什么是运算符重载 4.2运算符重载的方法 4.3重载运算符的规则 4.4运算符重载函数作为类成员函数和友元函 数 4.5重载双目运算符 4.6重载单目运算符 4.7重载流插入运算符和流提取运算符 4.8不同类型数据间的转换
4.1什么是运算符重载
C++ 为程序员提供了灵活的手段,让程序员自 己定义类,自己设计相应的运算符(必须在已 有的运算符基础上设计),使之应用于自己定 义的类。与函数重载类似,对已有的运算符赋 予新的含义,用一个运算符表示不同功能的运 算,这就是运算符重载。 实际上,我们在此之前已经使用了运算符重载。 如<<是C++的移位运算符,它又与流对象cout 配合作为流插入运算符,这是C++对<<进行了 重载处理。
C++中可以重载除下列运算符外的所有 运算符: . .* :: ?: sizeof() 只能重载C++语言中已有的运算符,不 可臆造新的。 不改变原运算符的优先级和结合性。 不能改变操作数个数。 经重载的运算符,其操作数中至少应该 有一个是自定义类型。

两种形式

重载为类成员函数。 重载为友元函数。
class Complex {public: Complex(){real=0;imag=0;} Complex(double r,double i){real=r;imag=i;} Complex operator + (Complex &c2); void display(); private: double real; double imag; };
例4.1 通过成员函数实现复数的加法。 class Complex { private: double real; double imag; public: Complex(){real=0;imag=0;} Complex(double r,double i){real=r;imag=i;} Complex complex_add(Complex &c2); void display(); };
合集下载

编程技术中的运算符重载和函数重载

编程技术中的运算符重载和函数重载

编程技术中的运算符重载和函数重载编程技术中的运算符重载和函数重载是两个非常重要的概念。

它们可以让程序员更加灵活地使用已有的运算符和函数,从而提高编程效率和代码可读性。

本文将分别介绍运算符重载和函数重载的概念、用法和应用场景。

一、运算符重载运算符是编程语言中的一种特殊符号,用于表示不同的数学和逻辑运算。

在传统的编程语言中,每个运算符都有固定的语义和操作对象。

但是,在某些情况下,我们可能希望对已有的运算符进行自定义的操作。

这就是运算符重载的概念。

运算符重载可以让程序员重新定义运算符的操作行为。

通过重载运算符,我们可以使得运算符对用户自定义的类型也能够进行操作。

例如,我们可以定义一个名为"Vector"的类,然后重载"+"运算符,使得两个"Vector"对象可以相加。

这样,我们就可以像操作普通的整数或浮点数一样,对"Vector"对象进行加法运算。

运算符重载的语法和用法因编程语言而异。

在C++中,运算符重载通过定义特殊的成员函数来实现。

例如,重载"+"运算符的成员函数的定义如下:```cppclass Vector {public:Vector operator+(const Vector& other) {Vector result;// 实现向量相加的逻辑return result;}};```通过重载运算符,我们可以使得代码更加简洁和易读。

例如,我们可以使用如下方式对两个"Vector"对象进行相加:```cppVector v1, v2;Vector sum = v1 + v2;```二、函数重载函数重载是指在同一个作用域中,可以定义多个同名函数,但是这些函数的参数列表必须不同。

函数重载可以让程序员使用相同的函数名来实现不同的功能,从而提高代码的可读性和复用性。

函数重载的用法非常灵活。

第04章 运算符重载

第04章 运算符重载
算符被重载后其原有的功能仍然保留已有算符的作用范载使之能用于载载象算符重载和载载合起可以在程序中定载出有载用意载而使用方便的新的据载型最吸引人的特点之一?43重载中载大部分的算符允载重载43重载不能重载的算符只有算符不能重载是载了保载载载成载的功能不能被改载两个运参数个数不能全部是参数以防止用载修改用于载准载型intoperatorint不合法43returnab
class A { int i; public: A(int a=0){ i=a;} void Show(void) {cout<<"i="<<i<<endl;} void AddA(A &a, A &b) // 利用函数进行类之间的运算 { i=a.i+b.i; } A operator +(A &a) // 重载运算符+ { A t; t.i=i+a.i; return t; } }; void main(void) { A a1(10),a2(20),a3; 相当于a3=a1.operator+(a2) a1.Show (); a2.Show (); a3=a1+a2; //重新解释了加法,可以直接进行类的运算 a3.AddA(a1,a2); //调用专门的功能函数 a3.Show (); }
总结:
重新定义运算符,由左操作符
调用右操作符。最后将函数返
回值赋给运算结果的对象。
由对象c1调用
若已有运算载Complex operator+ (Complex &c1, Complex &c2) ,那下面的表达式还 合法吗 c3=c2+12; // 这个表达式合法吗? int i=3+5; //这个表达式合法吗?

第4讲 运算符重载(上)

第4讲 运算符重载(上)
10
重载函数作为类的友元函数
11
小结
C++规定,有的运算符(如赋值运算符、下标运算符、 C++规定,有的运算符(如赋值运算符、下标运算符、函数 规定 调用运算符)必须定义为类的成员函数, 调用运算符)必须定义为类的成员函数,有的运算符则不能 定义为类的成员函数(如流插入“<<” 定义为类的成员函数(如流插入“<<”和流提取运算符 >>” 类型转换运算符) “>>”、类型转换运算符) 一般将单目运算符重载为成员函数, 一般将单目运算符重载为成员函数,将双目运算符重载为 友元函数 说明: 有的C++编译系统( C++编译系统 6.0)没有完全实 说明: 有的C++编译系统(如Visual C++ 6.0)没有完全实 C++标准 它所提供不带后缀. 标准, 现C++标准,它所提供不带后缀.h的头文件不支持把成员函 数重载为友元函数。但是Visual C++所提供的老形式的带 数重载为友元函数。但是Visual C++所提供的老形式的带 后缀. 后缀.h的头文件可以支持此项功能
第4讲 运算符重载
4.1 运算符重载概念 4.2 重载运算符的规则
1
4.1 运算符重载概念
重载概念:用户根据自己需要对C++已提供的运算符 或函数的功能重新赋予新的含义,使之“一词多义”
函数重载:同一函数名可以实现不同的功能 运算符重载:同一运算符能实现不同的运算操作
2
生活中的重载概念
“杯具”一词重 杯具” 载
12
本讲重点
重载的概念:“双肩挑” 重载的方法: 重载的方法:运算符重载是通过定义函 数实现的 重载的规则:7+1

第4章运算符重载

第4章运算符重载
6
C++语言程序设计
int main( ) { Complex c1(3,4),c2(5,-10),c3;
c3=plex_add(c2); //调用复数相加函数
cout<<"c1="; c1.display(); cout<<"c2="; c2.display(); cout<<"c1+c2="; c3.display(); return 0; }
24
C++语言程序设计
(1)先建立一个String类:见C4-4-1(VC++).CPP #include <iostream> using namespace std; Class String //String 是用户自己指定的类名 {public:
String( ){ p=NULL; } //默认构造函数 String( char *str ); //构造函数 void display( ); private: char *p; //字符型指针,用于指向字符串 };
1、掌握运算符重载的基础知识。 2、掌握运算符重载函数为类成员函数及友元函数
的方法。 3、熟悉不同类型数据间的转换。
【重点】
运算符重载的方法;运算符重载函数作为类成员 函数;运算符重载函数作为友元函数;单目运算符 重载;不同类型数据之间的转换。
【难点】
单目运算符重载函数;不同类型数据间的转换。
2
C++语言程序设计
重载函数operator+是作为Complex类中的
成员函数的。
由于重载函数是Complex类中的成员

4第四章 运算符重载

4第四章 运算符重载
1 2 3
const complex operator - (const complex &c) const; void display(); //输出复数 private: //私有数据成员 1.是为了堵塞a+b=c的漏洞。 double real; //复数实部 2. 3.是为了扩大适应性。 double imag; //复数虚部 };
17
[ ]运算符重载为成员函数
下标运算符[]可以重载: 重载形式为:operator[](int); 当 X x; 隐含调用。 x[y] 可被解释为: 显式调用。 x. operator [ ](y); 只能重载为成员函数,不能使用友元函数。 这个类显然是个‚数组类‛。
18
前置++和后置++重载为成员函数
9
使用
void main(){
complex c1(5,4),c2(2,10),c3; //三个复数类的对象 cout<<"c1="; cout<<"c2="; c1.display(); c2.display();
c3=c1-c2; //使用重载运算符完成复数减法 cout<<"c3=c1-c2="; c3.display(); 程序输出结果为:
这三个运算符是许多 教课书没有提到的。
唯一的一个三目运 算符不能重载。
3
运算符重载的基础
设计运算符重载函数,首先要了解运算符原本的运算语义。重
载函数要忠实遵守该运算符作用于基本数据类型时的语义,
并表现出自身所特有的性质。 例如:+ 、+= 、=、++(前)、++(后) ....

运算符重载

运算符重载

1、多态性的基本概念2、派生类对象替换基类对象3、虚函数的定义4、抽象类的定义5、宠物类的设计6、运算符重载7、日期类对象判断大小8、分数类对象运算符重载☐运算符重载指赋予运算符新的操作功能,主要用于对类的对象的操作☐运算符+意味着多少对象类型的加法呢?☐还可以定义新的对象类型加法☐运算符重载定义形式:<类型><类名>::operator<操作符>(<参数表>){函数体}☐首先定义虚数类☐虚数可以描述为:a+bi☐a与b看成实数,定义成double类型☐成员函数除了构造与析构外,还有:☐输出虚数、修改虚数、得到实部a、得到虚部b ☐相加+、判相等==#include <iostream>using namespace std;class Complex{private:double real, imag;public:Complex(double r = 0, double i = 0): real(r), imag(i){ }double Real(){return real;}double Imag(){return imag;}Complex operator +(Complex&);Complex operator +(double);bool operator ==(Complex);~Complex(){ };Complex Complex::operator +(Complex &c)// 重载运算符+,两边是虚数对象{Complex temp;temp.real = real+c.real;temp.imag = imag+c.imag;return temp;}Complex Complex::operator +(double d)// 重载运算符+,左边是虚数对象,右边是双精度数{Complex temp;temp.real = real+d;temp.imag=imag;return temp;}bool Complex::operator ==(Complex c)// 重载运算符=={if (real == c.real && imag == c.imag)return true;elseint main(){Complex c1(3,4),c2(5,6),c3;cout << "C1 = " << c1.Real() << "+j" << c1.Imag() << endl;cout << "C2 = " << c2.Real() << "+j" << c2.Imag() << endl;c3 = c1+c2;cout << "C3 = " << c3.Real() << "+j" << c3.Imag() << endl;c3 = c3+6.5;cout << "C3 + 6.5 = " << c3.Real() << "+j" << c3.Imag() << endl;if ( c1==c2 )cout<<“两个复数相等”;elsecout<<“两个复数不相等”;return 0;☐运算符++分前置运算符和后置运算符☐例如: ++Y与Y++☐前置运算符定义Complex Complex::operator ++ () {real+=1;return *this;}☐后置运算符定义Complex Complex::operator ++ (int) {real+=1;return *this;}。

4 运算符重载


可以将+代表的操作看成一个函数:+为函数的名字,+操作的两个操 作数的类型即为函数形参的类型,+操作的结果的类型即为函数的返回 值类型。
北京化工大学 VC++ 教学课件
2
计算机系 江志英 jiangzy@
运算符重载的提出
C/C++中,每种基本数据类型的变量都可通过几种运算符来做相关计 算,如int型变量,它们可以同“+”,“-”,“*”,“/”等运算符 来做加法,减法,乘法,除法等。如:
4 5 6
常用运算符的重载
重载赋值运算符operator=
重载输入/输出运算符 << | >>
重载下标运算符operator[ ]
重载类型转换函数
北京化工大学 VC++ 教学课件
4
计算机系 江志英 jiangzy@
运算符重载的基本语法
运算符的使用和普通函数在语法上有所不同,但是可以将 运算符看作是一种特殊的函数,操作数是函数的参数,运 算结果是函数的返回值。
北京化工大学 VC++ 教学课件
14
计算机系 江志英 jiangzy@
// 重载运算符的使用示例 int main() { Byte a, b, *bp; +b; -b; ~b; bp = &b; !b; ++b; b++; --b; b--; } //end of main()
3
Vector vec1,vec2 vec1+vec2; vec1-vec2; vec1*vec2; vec1/vec2; 两个向量类对象的加减乘除
C++提供了运算符重载机制来帮助我们实现上述目的。

第四章 运算符重载


例:给出以下程序的运行结果。
#include <iostream.h> <iostream. int square(int x) { return x*x; x*x; } 此程序的运行结果为: double square(double y) The square of integer 7 is 49 { return y*y; y*y; The square of integer 7.5 is 56.25 } main() { cout<<” cout<<”The square of integer 7 is”<<square(7)<<endl; is”<<square(7)<<endl; cout<<” cout<<” The square of double 7.5 is”<<square(7.5)<<endl; is”<<square(7 )<<endl; return 0; }
函数重载
重载: 重载:
在同一作用域, 在同一作用域 , 允许多个函数使用同一名 字的措施。 字的措施。 名字相同, 参数个数或者 参数对应位置 名字相同 , 但 参数个数 或者参数对应位置 的类型不同,这样的函数称为重载 (overloading)。 overloading) 例如: int func(); func(); int func(int a,int b); b); void func(char *a,int b); b);
运算符重载
只听过数学中可以有运算, 对象之间也可以加减乘除???
运算符重载
C++语言允许程序员重新定义已有的运算符,使 C++语言允许程序员重新定义已有的运算符,使 其能按用户的要求完成一些特定的操作,这就是所谓 的运算符重载。运算符重载与函数重载相似,其目的 是设置某一运算符,让它具有另一种功能,尽管此运 算符在原先C++语言中代表另一种含义,但他们彼此 算符在原先C++语言中代表另一种含义,但他们彼此 之间并不冲突。C++会根据运算符的位置辨别应使用 之间并不冲突。C++会根据运算符的位置辨别应使用 哪一种功能进行运算。

运算符重载


运算符重载为类的友元函数
类中的声明: 类中的声明: friend 函数类型 operator 运算符(参数表); 运算符(参数表); 运算符重载函数的定义形式: 运算符重载函数的定义形式: 运算符(参数表) 函数类型 operator 运算符(参数表) { 函数体; 函数体; } 附加例) (附加例)用友元函数实现复数的加法运算符的重 载。
数据类型转换 标准数据类型转换
隐式转换: 自动转成double型) 隐式转换:7.5+2 (将2自动转成 将 自动转成 型 显式转换: 转成整型) 显式转换:int(89.5) (将89.5转成整型 将 转成型
涉及到类类型的转换
对于用户自己声明的类型, 对于用户自己声明的类型,编译系统并不知道怎样进行转 换。解决这个问题的关键是让编译系统知道怎样去进行转 换,需要定义专门的处理函数。 需要定义专门的处理函数。 将一个其他类型的数据转换成一个类类型: 将一个其他类型的数据转换成一个类类型:转换构造函数 将一个类的对象转换成另一类型的数据: 将一个类的对象转换成另一类型的数据:类型转换函数
运算符重载的格式
运算符重载为类的成员函数 运算符重载为类的友元函数
运算符重载的规则
①
② ③ ④ ⑤
.”、 *” ::”、 ?:”和 sizeof”等几个运 除“. 、“*”、“:: 、“?: 和“sizeof 等几个运 算符不能重载外, 算符不能重载外,C++中几乎所有的运算符都可以 中几乎所有的运算符都可以 重载。 重载。 运算符被重载后,其优先级和结合性不会改变。 运算符被重载后,其优先级和结合性不会改变。 不能改变运算符操作对象的个数。 不能改变运算符操作对象的个数。 运算符的意义应不变。 运算符的意义应不变。 用于类对象的运算符一般必须重载,但有两个例外, 用于类对象的运算符一般必须重载,但有两个例外, 运算符“ 和 不必用户重载。 运算符“=”和“&”不必用户重载。 不必用户重载

第四章运算符重载


2、对于任意一元运算符α:
(1)成员函数重载运算符
定义
type x::operator α( )
{…}
显式调用
objX.operator α( )
隐式调用
αobjX 或:ojbXα
(2)友元函数重载运算符
定义
type operator α(Xobj)
{…}
显式调用
operatorα(obj X)
隐式调用
友元函数重载运算符时,需要明确给出参数,不会出错。 3、不能用友元函数重载的运算符:
= 、 ( )、[]、- > 4、注意: (1)对THIS所指向的数据的任何改变都会影响到激活运算数函数的对象。 (2)可使用引用参数(指针)来解决重载时的二义性。
4.1.5 重载++和--
一、关于++和- 1、C中的++和- -的两种形式: 前缀:++i; 后缀:i--; 2、在C++中的约定 (显式地区分前缀和后缀) (1)对于前缀方式++i:
例4-1 1、重载“+”、“=”、“++”;读懂几个成员函数; 2、成员函数重载运算符,激活运算符的对象都是由THIS指针隐含传递的。
4.1.4 用友元函数重载运算符
1、成员函数重载可能造成的麻烦:成员函数重载的运算符不具有交换性。 原因:成员函数仅能被一个“实际对象”所调用,如果引起成员函数
调用的是一个值(非一个对象),成员函数将不能正确工作。 2、可用友元函数解决这一问题:
5、除“=”以外,重载的运算符可以被任何派生类所继承, “=”需要每个类明确定义自己的解释;
6、 重载可能让程序的可读性下降,在使用时应模仿运算符的 习惯用法 。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档