面向对象程序设计》讲义.ppt_第1页
面向对象程序设计》讲义.ppt_第2页
面向对象程序设计》讲义.ppt_第3页
面向对象程序设计》讲义.ppt_第4页
面向对象程序设计》讲义.ppt_第5页
已阅读5页,还剩74页未读 继续免费阅读

下载本文档

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

文档简介

面向对象程序设计讲义,第 9 章,9.1 函数重载 9.1.1 构造函数重载 举例:计时器实例 #include #include class timer /定义计时器类 int seconds; public: timer(); /声明四个重载函数 timer(char *t); timer(int t); timer(int, int);,第 9 章 重 载,int gettimer(); /此函数返回seconds的值 / ; timer:timer( ) /定义无参数构造函数,给seconds清零 seconds=0; timer:timer(int t) /定义一个整型参数的构造函数 seconds=t; timer:timer(char *t) /定义含一个字符串构造函数 seconds=atoi(t); timer:timer(int min,int sec) /定义一个含两个整型参 seconds=min*60+sec; /数的构造函数 int timer:gettimer() /取私有变量seconds的值 return seconds;,main() timer t1,t2(“123”),t3(23),t4(2,34); cout“object t1:”t1.gettimer()“n”; cout“object t2:”t2.gettimer()“n”; cout“object t3:”t3.gettimer()“n”; cout“object t4:”t4.gettimer()“n”; ,9.1.2 类成员函数重载 举例:一个日期类的例子 #include #include #include class date /定义日期类 int year; int month; int day; public: date() year=0;month=0;day=0; date(int,int,int); date(char *); void getdate(char *); void getdate(int *,int *,int *); ;,date:date(int yy,int mm,int dd) /传递整型参数的构造函数 year=yy; month=mm; day=dd; date:date(char *str) /传递字符串的构造函数 char *ss=new char5; /定义一个字符串,并为其分配内存 ss0=str0; /取字符串前两个字符,为月份 ss1=str1; ss2=0; month=atoi(ss); /将字符串转换成整数 ss0=str3; /取字符串中的第4,5个字符,为日期 ss1=str4; day=atoi(ss);,ss0=2; ss1=0; ss2=str6; /取字符串中的第7,8个字符,为年份 ss3=str7; ss4=0; year=atoi(ss); delete ss; /释放分配的内存 ,void date:getdate(char *str) char *ss=new char5; itoa(month,ss,10); /将month转换成字符串给ss, 10为进制 if(month10) ss1=ss0; /若月份小于10,在第一位加上0 ss0=0; ss2=0; strcpy(str,ss); /字符串赋值 itoa(day,ss,10); /将day转换成字符串给ss strcat(str,”/”); /在日期字符串中的月份后加入分隔符 if(day10) ss1=ss0; /日期小于10,第一位加0 ss0=0;,ss2=0; strcat(str,ss); /将ss加到str后面 itoa(year,ss,10); /将year转换成字符串给ss ss0=/; ss1=ss2; ss2=ss3; ss3=0; strcat(str,ss); /将ss加到str后面 delete ss; date:getdate(int *yy,int *mm,int *dd) /将年、月、日值分别赋给三个整数 *yy=year; *mm=month; *day=dd; ,main() int *yy=new int,*mm=new int,*dd=new int; char *datt=new char9; date da1,da2(2008,4,09),da3(“03/01/02”); da2.getdate(datt); da3.getdate(yy,mm,dd); coutdatt“n”; cout*yy“ ”*mm“ ”*dd“n”; delete yy,mm,dd,datt; ,/- #include #pragma hdrstop #include “U9_1_2.h“ /- #pragma package(smart_init) #pragma resource “*.dfm“ TForm1 *Form1; /* class date / int year; int month; int day;,public: date( ) year=0;month=0;day=0; date(int,int,int); date(String); int gety( ) return year; int getm( ) return month; int getd( ) return day; ;,date:date(int yy,int mm,int dd) / year=yy; month=mm; day=dd; date:date(String str) / month=StrToInt(str.SubString(1,2); day=StrToInt(str.SubString(4,2); year=StrToInt(str.SubString(7,2); /-,void _fastcall TForm1:BtnRunClick(TObject *Sender) date da1,da2(2003,4,28),da3(“04/30/03“); Canvas-TextOutA(20,50,da1.gety(); Canvas-TextOutA(60,50,da1.getm(); Canvas-TextOutA(100,50,da1.getd(); Canvas-TextOutA(20,70,da2.gety(); Canvas-TextOutA(60,70,da2.getm(); Canvas-TextOutA(100,70,da2.getd(); Canvas-TextOutA(20,90,“200“+IntToStr(da3.gety(); Canvas-TextOutA(60,90,da3.getm(); Canvas-TextOutA(100,90,da3.getd(); ,9.2 运算符重载 注意事项:重载运算符时,不能改变它们的优先级,不能改变运算符所需操作数的数目。 9.2.1 用成员函数重载运算符 1. 用成员函数重载运算符的语法形式 (1)在类定义体中声明运算符函数: type operator (参数表) 注意事项:在参数表中,若运算符是一元的,则参数表为空,此时当前对象为运算符的单操作数;若运算符是二元的,则参数表中有一个操作数,此时当前对象作为运算符的左操作数,参数表中的操作数作为运算符的右操作数。,例如: class x / int operator +(x a); ; (2)定义运算符函数 type x:operator (参数表) /定义的操作 如上例的形式为: int x:operator + (x a) /. ,(3)重载运算符的使用 main( ) x a1,b1; y a2,b2; a1=a1+b1; / 正确 a2=a2+b2; / 错误 ,2. 用成员函数重载运算符的使用举例 #include class point int x,y; public: point(int vx,int vy) x=vx;y=vy; point() x=0,y=0; point operator +(point p1); /重载运算符“+” point operator (point p1); /重载运算符“” void print()coutx“ ”y“n”; ;,point point:operator +(point p1) /定义两个对象的“+”函数 point p; p.x=x+p1.x; p.y=y+p1.y; return p; /返回当前对象与p1对象之和 point point:operator -(point p1) /定义两个对象的“”函数 point p; p.x=x-p1.x; p.y=y-p1.y; return p; /返回当前对象与p1对象之差 ,main() point p1(10,10),p2(20,20),p3(); p3=p1+p2; p3.print(); p3=p1-p2; p3.print(); ,/-三维空间上对象的坐标操作- #include #pragma hdrstop #include “U9_2_2_1_1.h“ /- #pragma package(smart_init) #pragma resource “*.dfm“ Tbc9_2_1_1 *bc9_2_1_1; /*- class three_d int x,y,z; public: three_d(int vx,int vy,int vz) x=vx;y=vy;z=vz;,three_d()x=0;y=0;z=0; three_d operator +(three_d t); three_d operator (three_d t); three_d operator =(three_d t); int getx()return x; int gety()return y; int getz()return z; ; three_d three_d:operator +(three_d t) three_d te; te.x=x+t.x; te.y=y+t.y; te.z=z+t.z; return te; /返回当前对象与t对象之和 ,three_d three_d:operator -(three_d t) three_d te; te.x=x-t.x; te.y=y-t.y; te.z=z-t.z; return te; three_d three_d:operator =(three_d t) /将t对象的值赋给当前对象 x=t.x; y=t.y; z=t.z; return *this; /对形如t3=t2=t1语句是必要的 /*,/- void fastcall Tbc9_2_1_1:btnRunClick(TObject *Sender) three_d t1(10,20,30),t2(40,50,60),t3; for(int i=1;iTextOutA(10,i*20,t3.getx(); Canvas-TextOutA(50,i*20,t3.gety(); Canvas-TextOutA(90,i*20,t3.getz(); /-,9.2.2 用友元重载运算符 1. 用友元重载运算符的语法形式 (1)在类定义体中声明重载运算符 friend type operator (参数表) 注意事项:在参数表中,若重载的是一元运算符,则在参数表中有唯一的操作数;若重载的是二元运算符,则在参数表中有两个操作数。 (2)定义重载运算符 type operator (参数表) /定义的操作 ,2. 用友元重载运算符的使用举例 例2. /-用重载运算符的方法进行集合运算- #include #pragma hdrstop #include “U9_2_2_2.h“ /- #pragma package(smart_init) #pragma resource “*.dfm“ Tf9_2_2_2 *f9_2_2_2; /*- const maxcard=16; enum errcodenoerr,overflow;,class set /定义集合类 int elemsmaxcard; int card; public: set()card=0; errcode addelem(int); /增加集合元素 void print(int,int); /输出集合元素 friend bool operator /声明重载运算符!=,判定两个集合是否不等,friend set operator *(set,set); /声明重载运算符*,求两个集合之交 friend set operator +(set,set); /声明重载运算符+,求两个集合之并 friend bool operator (set,set); /声明重载运算符,判某一集合是否为另一集合的纯子集 friend bool operator =(set,set); /声明重载运算符=,判某一集合是否为另一集合的子集 ;,errcode set:addelem(int elem) /定义向集合中追加元素的成员函数 for(int i=0;icard;i+) if(elemsi=elem) return noerr; if(cardmaxcard) elemscard+=elem; return noerr; else return overflow; ,void set:print(int ii, int jj) for(int i=0;iCanvas- TextOut (30*(1+i)+ii, 20+20*jj,elemsi); bool operator ,bool operator =(set set1,set set2) if(set1.card!=set2.card)return false; for(int i=0;iset1.card;i+) /循环判set1中的每个元素是否属于set2 if(!(set1.elemsi /调用上面的“=“定义 ,set operator *(set set1,set set2) set res; for(int i=0;iset1.card;i+) for(int j=0;jset2.card;j+) if(set1.elemsi=set2.elemsj) /取set1中的每一个元素判是否属于set2,若属于则加入到res中去 res.elemsres.card+=set1.elemsi; break; return res; ,set operator +(set set1,set set2) set res=set1; /先将set1赋给res for(int i=0;iset2.card)return false; for(int i=0;iset1.card;i+) /循环判set1中的元素是否属于set2 if(!(set1.elemsi ,bool operator (set set1,set set2) if(set1.cardset2.card /*- _fastcall Tf9_2_2_2:Tf9_2_2_2(TComponent* Owner) : TForm(Owner) /-,void_fastcall Tf9_2_2_2:btnRunClick(TObject *Sender) set set1,set2,set3; set1.addelem(30); set1.addelem(20); set1.addelem(40); set1.addelem(60); set1.addelem(70); set1.addelem(90); set1.addelem(390); set1.addelem(49); set2.addelem(39); set2.addelem(40); set2.addelem(50);,set2.addelem(60); set2.addelem(78); set2.addelem(480); set2.addelem(290); set2.addelem(77); f9_2_2_2-Canvas-TextOut(25,20,“set1中包含元素:“); set1.print(120,0); f9_2_2_2-Canvas-TextOut(25,40,“set2中包含元素:“); set2.print(120,1); if(20,if(set1=set2) f9_2_2_2-Canvas-TextOut(25,80,“set1=set2“); else f9_2_2_2-Canvas-TextOut(25,80,“set1!=set2“); set3=set1*set2; f9_2_2_2-Canvas-TextOut(25,100,“set1与set2的交集是:“); set3.print(150,4); if(set1Canvas-TextOut(25,120,“set1是set2的纯子集“); else f9_2_2_2-Canvas-TextOut(25,120,“set1不是set2子集“);,if(set3Canvas-TextOut(25,140,“set3是set1的纯子集”); else f9_2_2_2-Canvas-TextOut(25,140,“set3不是set1纯子集“); set3=set1+set2; f9_2_2_2-Canvas-TextOut(25,160,“set1与set2的并集:“); set3.print(0,8); /- void _fastcall Tf9_2_2_2:btnEndClick(TObject *Sender) Close(); /-,运行结果: set1中包含元素:30 20 40 60 70 90 390 49 set2中包含元素:39 40 50 60 78 480 290 77 set1中包含元素20 set1!=set2 set1与set2的交集是:40 60 Set1不是set2的子集 Set3是set1的纯子集 Set1与set2的并集是: 30 20 40 60 70 90 390 49 39 50 78 480 290 77,9.2.3 +和 的重载 /- #include #pragma hdrstop #include “U9_2_3_1.h“ /- #pragma package(smart_init) #pragma resource “*.dfm“ Tbc9_2_3 *bc9_2_3; /*-,class counter /定义计数器类 unsigned int value; public: counter()value=0; /初值清零 void operator +(); /重载声明“+” void operator -(); /重载声明“-” int get()return value; ; void counter: operator +() if(value0)value-; ,/* _fastcall Tbc9_2_3:Tbc9_2_3(TComponent* Owner) : TForm(Owner) /- void _fastcall Tbc9_2_3:btnRunClick(TObject *Sender) counter c1; for(int i=0;iTextOut(50,30,IntToStr(c1.get(); c1-; c1-; Canvas-TextOut(50,50,IntToStr(c1.get(); ,/- void _fastcall Tbc9_2_3:btnEndClick(TObject *Sender) Close(); /- 运行结果为: 10 8,9.2.4 运算符 和( )的重载 注意事项: 和( )不能用友元函数重载,只能用成员函数重载。 /-矩阵运算举例- #include #pragma hdrstop #include “U9_2_4.h“ /- #pragma package(smart_init) #pragma resource “*.dfm“ Tbc9_2_4 *bc9_2_4;,/*- class matrix /定义矩阵类 short rows,cols; /矩阵的行、列 double *elems; /双精度数组存放矩阵中各元素,按行存放 public: matrix(short rows,short cols); /matrix();若用自己定义的析构函数,出错 double operator () (short row,short col); /重载运算符“()”,用来返回元素值 void setelem(short row,short col,double val); /给元素赋值,friend matrix operator +(matrix p,matrix q); /重载运算符“+“,实现矩阵相加 friend matrix operator -(matrix p,matrix q); /重载运算符“-“,实现矩阵相减 friend matrix operator *(matrix p,matrix q); /重载运算符“*“,实现矩阵相乘 void print(int,int); /输出矩阵中各元素 ;,matrix:matrix(short rows,short cols) /定义构造函数 matrix:rows=rows; matrix:cols=cols; elems=new doublerows*cols; /为矩阵动态分配存储 /*matrix:matrix() delete elems; */,double matrix:operator () (short row,short col) return(row=1 /*按顺序存放矩阵元素,给出行、列值,算出在elems中的下标*/ ,matrix operator +(matrix p,matrix q) matrix m(p.rows,q.cols); if(p.rows!=q.rows|p.cols!=q.cols) return m; for(int r=1;r=p.rows;r+) for(int c=1;c=p.cols;+c) m.setelem(r,c, p(r,c)+q(r,c) ); /p(r,c)和q(r,c)使用了前面定义的重载运算符“()” return m; ,matrix operator -(matrix p,matrix q) matrix m(p.rows,q.cols); if(p.rows!=q.rows|p.cols!=q.cols) return m; for(int r=1;r=p.rows;r+) for(int c=1;c=p.cols;+c) m.setelem(r,c, p(r,c)-q(r,c) ); return m; ,matrix operator *(matrix p,matrix q) matrix m(p.rows,q.cols); if(p.cols!=q.rows) return m; for(int r=1;r=p.rows;r+) for(int c=1;c=q.cols;+c) m.setelem(r,c,0.0); for(int i=1;i=p.cols;i+) m.setelem(r,c,m(r,c)+p(r,i)*q(i,c); return m; ,void matrix:print(int ii, int jj) for(int r=1;rrows;r+) int kk=ii; for(int c=1;ccols;c+) bc9_2_4-Canvas-TextOut(30*ii,25*jj, FloatToStr(*this)(r,c); ii+; ii=kk; jj+; ,/*- _fastcall Tbc9_2_4:Tbc9_2_4(TComponent* Owner) : TForm(Owner) /- void _fastcall Tbc9_2_4:btnEndClick(TObject *Sender) Close(); ,/- void _fastcall Tbc9_2_4:btnRunClick(TObject *Sender) matrix a(2,3),b(2,3),c(3,3),d(2,3),e(2,3); a.setelem(1,1,1.0); a.setelem(1,2,2.0); a.setelem(1,3,3.0); a.setelem(2,1,4.0); a.setelem(2,2,5.0); a.setelem(2,3,6.0); b.setelem(1,1,1.0); b.setelem(1,2,2.0);,b.setelem(1,3,3.0); b.setelem(2,1,4.0); b.setelem(2,2,5.0); b.setelem(2,3,6.0); c.setelem(1,1,1.0); c.setelem(1,2,4.0); c.setelem(2,1,2.0); c.setelem(2,2,5.0); c.setelem(3,1,3.0); c.setelem(3,2,6.0); c.setelem(1,3,7.0); c.setelem(2,3,8.0);,c.setelem(3,3,9.0); a.print(1,1); b.print(1,3); c.print(1,5); d=a+b; d.print(6,1); d=a-b; d.print(6,3); e=a*c; e.print(6,5); /-,程序简要说明:,9.2.5 new和delete的重载 new重载的一般形式: void *class_name:operator new(size_t,); 即:new重载应返回一个无值型的指针,且至少有一个类型 为size_t的参数。若该重载带有多于一个的参数,则第一 个参数的类型必须为size_t。 C+预定义的数据类型 size_t被说明为: typedef unsigned size_t;,/-new和delete的重载- #include #pragma hdrstop #include “U9_2_5.h“ /- #pragma package(smart_init) #pragma resource “*.dfm“ Tbc9_2_5 *bc9_2_5; /*-,const maxpoints=512; static struct block int x,y; block *next; block1maxpoints; /定义一个静态数组,用来申请内存使用 class point int x,y; static block *freelist; /空闲链头指针 static int used; /实际用掉的数组元素个数 /这两个静态数据是为了此类的所有对象都能共享 public:,point(int vx=0, int vy=0) x=vx;y=vy; void *operator new(size_t); void operator delete(void *ptr); void print(int,int); ;,void *point:operator new(size_t) block *res=freelist; /将空闲链头给res if(usednext; return res; /返回分配地址,可能还是数组形式,也许已 /为空闲链中取,也许为0 ,void point:operator delete(void *ptr) /将待释放内存块放入空闲链头 (block *)ptr)-next=freelist; /将待释放内存块插入到链头 freelist=(block *)ptr; /修改空闲链头指针 void point:print(int ii,int jj) bc9_2_5-Canvas-TextOut(10,6,“X,Y的值为:“); bc9_2_5-Canvas-TextOut(30*ii,25*jj,IntToStr(x); bc9_2_5-Canvas-TextOut(30*ii+15,25*jj,“,“); bc9_2_5-Canvas-TextOut(60*ii,25*jj,IntToStr(y); ,block *point:freelist=0; /给静态数据赋初值,空闲链初值为空 int point:used=0; /所用的数组元素个数的初值为0 /*- _fastcall Tbc9_2_5:Tbc9_2_5(TComponent* Owner) : TForm(Owner) /- void _fastcall Tbc9_2_5:Btn1Click(TObject *Sender) point *pt; pt=new point(5,7); pt-print(1,1); ,block *point:freelist=0; /给静态数据赋初值,空闲链初值为空 int point:used=0; /所用的数组元素个数的初值为0 /*- _fastcall Tbc9_2_5:Tbc9_2_5(TComponent* Owner) : TForm(Owner) /- void _fastcall Tbc9_2_5:Btn1Click(TObject *Sender) point *pt; pt=new point(5,7); pt-print(1,1); ,9.2.6 赋值运算符的重载 注意事项:运算符“=”只能被重载为成员函数 1. 指针悬挂问题: class string char *contents; int size; public: string(int sz) contents=new charsz; string()delete contents; ; main() string s1(10); string s2(20); s1=s2; ,2. 用运算符“=”重载解决 指针悬挂问题: #include class string char *contents; int size; public: / void operator =(string *); /重载赋值运算符

温馨提示

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

评论

0/150

提交评论