9运算符重载第章_第1页
9运算符重载第章_第2页
9运算符重载第章_第3页
9运算符重载第章_第4页
9运算符重载第章_第5页
免费预览已结束,剩余27页可下载查看

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第9章 运算符重载-2-本章内容安排基本概念递增运算符赋值运算符转换运算符重载输入输出流运算符-3-class Complexprivate:double real,imag;public:Complex() : real(0), imag(0) Complex(double r,double i):real(r), imag(i) Complex(const Complex& c):real( c.real), imag( c.imag ) void output() const;1、复数类Complex-4-#include void Complex:output() const if(i

2、mag=0) std:coutreal +imagistd:endl; else std:coutrealimagistd:endl;int main()Complex a(3,4),b(4,5);a.output();b.output();return 0;测试复数类-5-2、复数类加法复数类还应该实现加法运算,2个复数相加得到一个新的复数。解决方案一:定义成员函数add,实现加法运算。成员函数方案不直观,使用更复杂。解决方案二:重载运算符。-6-class Complexpublic:Complex add(const Complex& c) const; .;Complex Comple

3、x:add(const Complex &c) constdouble x,y;x=real+c.real;y=imag+c.imag;Complex tmp(x,y);return tmp;成员函数实现加法运算声明两个复数相加的成员函数,返回复数对象加法函数返回一个新的复数对象add声明为常成员函数传入参数也是常引用注意:返回值不能为引用-7-int main()Complex a(3,4),b(4,5),c;a.output();b.output();c = a.add(b);c.output();return 0;测试复数类a.add(b)返回一个临时复数对象(保存a和b相加结果), 临

4、时对象赋值给c。add方法实现复数加法,但不直观。-8-从简单数据类型开始思考运算符的实质?表达式 9/2=4,而9.0/2.0=4.5 。这里的同一个运算符“/ ”,由于所操作的数据不同而具有不同的意义,为什么?如何实现的?C +是由函数组成的,在C+内部,任何运算都是通过函数来实现的。在处理表达式 8+7时,C +将这个表达式解释成如下的函数调用表达式: operator + ( 8, 7 );相同的运算符对不同数据有不同的操作,实质上是函数的重载!3、引入运算符重载的概念-9-C+已经为各种基本数据类型定义了可能的运算符函数,如operator+ (int,int)operator- (

5、int,int)operator/(int,int);operator/(double, double);如果想让类的对象也能使用这些运算符,就需要重载对应的运算符。引入运算符重载的概念-10-class Complexpublic: Complex operator+(const Complex &c) const; ;Complex Complex:operator+ (const Complex& c) constreturn Complex(real+c.real,imag+c.imag); int main()Complex a(3,4),b(4,5), c;c = a + b; .

6、4、运算符重载实现加法运算重载Complex类的+运算符,operator+相当于函数名完整源代码:Complex工程a+b相当于a.operator(b), 返回临时复数对象, 将临时对象赋值给c。-11-本章内容安排基本概念递增运算符赋值运算符转换运算符重载输入输出流运算符-12-class Counterpublic: Counter() : value(0) Counter() int getValue() const return value; void setValue(int x) value = x; private: int value;计数器类CounterCounter类

7、主要用于计数,但目前不能执行递增(+)、 递减等运算,使用不方便。-13-class Counter public: const Counter& operator+(); ;const Counter& Counter:operator+() +value; return *this; int main() Counter c; std:cout c: c.getValue() n; +c; std:cout c: c.getValue() n; return 0;为Counter类重载前置+c先递增value的值,返回对c的引用,通 返回常引用可以提高效率,同时防止修改。+c相当于调用c.

8、operator+()-14-class Counterpublic:const Counter operator+( int ); ;const Counter Counter:operator+(int) Counter temp(*this); +value; return temp;为Counter类重载后置+为区分后置+和前置+,后置+的 operator+函数添加1个int参数后置+先返回变量的值,再对变量递增; 后置+返回1个临时对象,而不是引用。前置+,先递增值,再返回当前对象的引用-15-#include int main() Counter c; std:cout c: c

9、.getValue() n; c+; std:cout c: c.getValue() n; Counter a = c+; std:cout a: a.getValue() n;Counter b = +c; std:cout b: b.getValue() n;return 0;测试Counter的递增功能前置+,先递增,再返回引用。后置+,先保存备份,递增备份,返回原先的备份。-16-运算符重载的约束运算符重载是C+的强大功能和特色,多数运算符都能够进行重载,有一些约束。不允许重载内置类型的运算符;不能改变运算符的优先级和目数;不能创建新的运算符,如将*声明为指数运算改变运算符的语义是合

10、法的,如重载+进行减法运算,但会导致代码难以理解。重载运算符的初衷就是便于使用和易于理解。-17-本章内容安排基本概念递增运算符赋值运算符转换运算符重载输入输出流运算符-18-赋值运算符相同类型对象之间赋值时,实际上是通过调用operator=成员函数实现的。如果类中没有定义该函数,编译器会提供默认的赋值运算符,实现对象数据成员的逐一赋值。如果类中只包含简单数据成员,默认赋值运算符就能很好工作。如果类中包含指针成员,它们指向堆中分配的内存,默认赋值运算符会导致“浅复制”,造成内存泄漏或程序异常。此时需要编写自己的复制运算符函数-19-Tricycle类class Tricyclepublic:

11、 Tricycle(); Tricycle(const Tricycle& rhs); Tricycle(); Tricycle& operator=(const Tricycle& rhs); int getSpeed() const return *speed; void setSpeed(int newSpeed) *speed = newSpeed; private: int *speed;如果类中包含指向堆中的数据的指针成员, 应该自定义以下4个成员函数,而不是使用 缺省的函数:默认构造函数、拷贝构造 函数、析构函数、赋值运算符函数。赋值运算符修改左值,并返回左值的引用。 不应该返回

12、临时对象(教材有误)-20-Tricycle类Tricycle:Tricycle() speed = new int; *speed = 5;Tricycle:Tricycle(const Tricycle& rhs) speed = new int; *speed = rhs.getSpeed();Tricycle:Tricycle() delete speed; speed = NULL;构造函数中分配内存,析构函数中释放 内存。-21-Tricycle类Tricycle&Tricycle:operator=(const Tricycle& rhs) if (this = &rhs) re

13、turn *this; delete speed; speed = new int; *speed = rhs.getSpeed(); return *this;调用赋值运算符时,对象的内存已经 分配,因此要先释放内存,再重新 分配内存,然后复制现有的值。wichita=wichita会造成的意外错误, 要过滤这种情况,直接返回*this。复制构造函数:创建以现有对象为模板的新对象。赋值运算符函数:2个已经存在对象之间的赋值。-22-测试Tricycle类#include int main() Tricycle wichita; wichita.setSpeed(6); std:coutWic

14、hita: wichita.getSpeed()n; Tricycle dallas; wichita = dallas; std:coutWichita: wichita.getSpeed()n; return 0;-23-本章内容安排基本概念递增运算符赋值运算符转换运算符重载输入输出流运算符-24-测试Counter#include int main()int beta = 5;Counter alpha = beta;std:cout“alpha: “alpha.getValue()“n”; return 0;编译错误,无法用整型变量初始化Counter对象-25-class Count

15、erpublic:Counter( int newValue ); ;Counter:Counter(int newValue): value(newValue) int main()int beta = 5;Counter alpha = beta;std:cout“alpha: “alpha.getValue()“n”; return 0;类型转换构造函数通过类型转换构造函数,编译器知道如何将1个整数 转换为1个Counter对象。alpha = 6; 将以6为参数构造1个 临时的Counter对象,再将临时 对象赋值给alpha。-26-将对象赋值给整数?int main()Counte

16、r gama(18);int delta= gama;std:cout“delta: “delta“n”; return 0;编译错误,无法用Counter对象初始化整型变量。-27-class Counterpublic:operator int(); ;Counter:operator int() return value; int()运算符使用对象赋值(或初始化)整型变量时,编译器将调用 operator int()转换函数。int main()Counter gama(18);int delta= gama;std:cout“delta: “ delta和运算符C+预定义了cout和cin输入输出流对象。cout为内置数据类型提供了重载的运算符,支持对它们的输入操作。如果希望自定义类支持cout和cin的操作,需要重载这些运算符。-30-class Counterpublic:friend std:ostream& operator(std:ostream& out, const Counter& c); .;重载输出运算符operator必须重载为友元函数,参数为输入流对象 和被输出对象,返回输出流对象,以支持连续输出。std:ostream& operator(std:ostream& out, const Counter& c)outc.getValue()std:

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论