C++程序设计课件:第4章NEW2014

上传人:ni****g 文档编号:574486444 上传时间:2024-08-16 格式:PPT 页数:73 大小:838KB
返回 下载 相关 举报
C++程序设计课件:第4章NEW2014_第1页
第1页 / 共73页
C++程序设计课件:第4章NEW2014_第2页
第2页 / 共73页
C++程序设计课件:第4章NEW2014_第3页
第3页 / 共73页
C++程序设计课件:第4章NEW2014_第4页
第4页 / 共73页
C++程序设计课件:第4章NEW2014_第5页
第5页 / 共73页
点击查看更多>>
资源描述

《C++程序设计课件:第4章NEW2014》由会员分享,可在线阅读,更多相关《C++程序设计课件:第4章NEW2014(73页珍藏版)》请在金锄头文库上搜索。

1、第四章第四章 类与对象类与对象2024/8/162类与对象n 本章重点q C+中的类q 对象的概念q 构造函数q 析构函数2024/8/163回顾:面向过程的设计方法n重点:q如何实现细节过程,将数据与函数分开。n形式:q主模块+若干个子模块(main()+子函数)。q模块是按功能来分的,所以也称功能块。在C+中称为一个函数,一个函数解决一个问题,即实现一个功能或一个操作。2024/8/164结构化程序与面向对象程序的比较问题:输入圆的半径,求圆的周长和面积数据描述:半径,周长,面积均用实型数表示数据处理:输入半径 r;计算周长 = 2*r ;计算面积 = * r 2 ;输出半径,周长,面积;

2、 2024/8/165方法一:用结构化方法编程,求圆的周长和面积#includeusing namespace std;void main () double r, girth, area ; const double PI = 3.1415 ; cout r ; girth = 2 * PI * r ; area = PI * r * r ; cout radius = r endl ; cout girth = girth endl ; cout area = area endl ;2024/8/166#includeusing namespace std;const double PI

3、= 3.1415 ;double girth(double r) return 2 * PI * r ;double area(double r) return 2 * r * r ;void main () double r,r1; cin r ; cout girth = girth(r) endl ; cout area = area(r) r1 ; cout girth = girth(r1) endl ; cout area = area(r1) endl ;2024/8/167面向对象的方法n目的:q实现软件设计的产业化。n观点:q自然界是由实体(对象)所组成。n程序设计方法:q使

4、用面向对象的观点来描述模仿并处理现实问题。面向对象技术中的对象就是现实世界中某个具体的物理实体在计算机逻辑中的映射和体现。n要求:q高度概括、分类、和抽象。2024/8/168方法二:用面向对象方法编程,求圆的周长和面积class Circle double radius ; public : void Set_Radius( double r ) radius = r ; double Get_Radius( ) return radius ; double Get_Girth( ) return 2 * 3.14 * radius ; double Get_Area( ) return 3

5、.14 * radius * radius ; ;void main() Circle A, B ; A.Set_Radius( 6.23 ) ; cout A.Radius = A.Get_Radius() endl ; cout A.Girth = A.Get_Girth() endl ; cout A.Area = A.Get_Area() endl ; B.Set_Radius( 10.5 ) ; cout B.radius = B.Get_Radius() endl ; cout B.Girth= B.Get_Girth() endl ; cout B.Area = B.Get_Ar

6、ea() endl ; 2024/8/169方法二:用面向对象方法编程,求圆的周长和面积 实例化实例化分析分析圆类圆类 数据成员数据成员 半径半径 成员函数成员函数 置半径值置半径值求圆的半径求圆的半径求周长求周长 求面积求面积有什么能干什么2024/8/1610方法二:用面向对象方法编程,求圆的周长和面积#includeusing namespace std;class Circle double radius ; public : void Set_Radius( double r ) radius = r ; double Get_Radius( ) return radius ; do

7、uble Get_Girth( ) return 2 * 3.14 * radius ; double Get_Area( ) return 3.14 * radius * radius ; ;Circle类定义类定义数据成员数据成员成员函数成员函数2024/8/1611方法二:用面向对象方法编程,求圆的周长和面积void main() Circle A, B ; A.Set_Radius( 6.23 ) ; cout A.Radius = A.Get_Radius() endl ; cout A.Girth = A.Get_Girth() endl ; cout A.Area = A.Get

8、_Area() endl ; B.Set_Radius( 10.5 ) ; cout B.radius = B.Get_Radius() endl ; cout B.Girth= B.Get_Girth() endl ; cout B.Area = B.Get_Area() endl ; 建立对象建立对象(类类型变量)(类类型变量)通过对象通过对象调用类的成员函数调用类的成员函数编写几个计算面积的函数,分别计算圆、矩形、梯形和三角形的面积#include #include using namespace std;const double PI= 3.14159;double area(doub

9、le radius=0);double area(double a, double b); double area(double a, double b, double h);double area(double a, double b, double c, int);2024/8/1612int main() coutArea of point is area( )n;coutArea of square is area(1,1)n;coutArea of circle is area(0.5)n;coutArea of trapezium is area(1,0.5,1)n;coutAre

10、a of triangle is area(1,sqrt(1+0.5*0.5),sqrt(1+0.5*0.5),0)n;return 0;2024/8/16132024/8/1614 类的引入:类的引入: 类是一种数据类型。类是一种数据类型。 描述客观事物必须描述客观事物必须用不同的数据类型用不同的数据类型来描述来描述不同不同的方面的方面。如商品:。如商品: 商品名称(用字符串描述),该商品数量(用整商品名称(用字符串描述),该商品数量(用整型数描述),该商品单价(用浮点数描述),该商品型数描述),该商品单价(用浮点数描述),该商品总价(用浮点数描述)。总价(用浮点数描述)。这里用了属于三种不

11、同数据类型的四个数据成员来描这里用了属于三种不同数据类型的四个数据成员来描述一种商品。述一种商品。C+类的定义 2024/8/1615class CGoodspublic : char Name21 ; int Amount ; float Price ; float Total_value ; ; /最后的分号不可少,这是一条说明语句最后的分号不可少,这是一条说明语句C+类的定义 数据类型说明符数据类型说明符类型名类型名访问限定符访问限定符2024/8/1616访问限定符访问限定符:public(公共的)(公共的)说明的成员能从外部进行访问。说明的成员能从外部进行访问。private(私有的

12、)(私有的)和和protected(保护的)(保护的)说明的成员不说明的成员不能从外部进行访问。能从外部进行访问。 每种说明符可在类体中使用多次。每种说明符可在类体中使用多次。 访问限定符的访问限定符的作用域作用域是从该说明符出现开始到下一个说是从该说明符出现开始到下一个说明符之前或类体结束之前结束。明符之前或类体结束之前结束。 如果在类体起始点无访问说明符,系统如果在类体起始点无访问说明符,系统默认定义为私有默认定义为私有(private)。)。 C+类的定义 2024/8/1617class 类名类名 private: 成员表成员表1; public: 成员表成员表2; protected

13、: 成员表成员表3; /注意:所有说明都以分号结束注意:所有说明都以分号结束其中其中“class 类名类名”称为称为类头类头花花括括号号中中的的部部分分称称为为类类体体,类类体体中中定定义义了了类类成成员员表表,包包含含数数据据和和函数函数。C+类的定义 2024/8/1618class CGoodsprivate : char Name21 ; int Amount ; float Price ; float Total_value ;public : void RegisterGoods(char,int,float); /输入数据输入数据 void CountTotal( ) ; /计算

14、商品总价值计算商品总价值 char * GetName() ; /读取商品名读取商品名 int GetAmount( ) ; /读取商品数量读取商品数量 float GetPrice( ) ; /读取商品单价读取商品单价 float GetTotal_value( ) ; /读取商品总价值读取商品总价值 ; C+类的定义 成员函数2024/8/1619通通常常在在类类定定义义中中,成成员员函函数数仅仅作作声声明明。函函数数定定义义通通常常在在类类的的说说明明之之后后进进行行,其其格格式如下:式如下:返回值类型返回值类型 类名类名:函数名函数名(参数表参数表) /函数体函数体其其中中运运算算符符

15、“:”称称为为作作用用域域解解析析运运算算符符,它指出该函数是属于哪一个类的成员函数。它指出该函数是属于哪一个类的成员函数。成员函数的定义 2024/8/1620类CGoods函数的定义void CGoods:RegisterGoods(char name , int amount , float price)strcpy(Name , name) ; /字符串复制函数字符串复制函数Amount=amount ; Price=price ;void CGoods:CountTotal(void) Total_value = Price*Amount;Char * CGoods:GetName(

16、 )return Name;int CGoods:GetAmount(void)return(Amount) ;float CGoods:GetPrice(void)return(Price) ;float CGoods:GetTotal_value(void)return(Total_value) ;2024/8/1621定义对象:定义对象: 对对象象是是类类的的实实例例。定定义义一一种种数数据据类类型型只只是是告告诉诉编编译译系系统统该该数数据据类类型型的的构构造造,并并没没有有预预定定内内存存。类类只只是是一一个个样样板板,以以此此样样板板可可以以在在内内存存中中开开辟辟出出同同样样结结

17、构构的的实实例例对象。格式如下:对象。格式如下:CGoods Car;这这个个定定义义创创建建了了CGoods类类的的一一个个对对象象Car,同同时时为为它它分分配配了了属属于于它它自自己己的的存存储储块块,用用来来存存放放数数据据和和对对这这些些数数据据实实施施操操作作的的成成员员函函数数(代代码码)。对对象象只只在在定定义义它它的的域域中有效。中有效。对象的创建与使用 2024/8/1622#includeusing namespace std;class Circle double radius ; public : void Set_Radius( double r ) ; doubl

18、e Get_Radius() ; double Get_Girth() ; double Get_Area() ; ;Circle类定义类定义数据成员数据成员成员函数成员函数回顾回顾 用面向对象方法编程,求圆的周长和面积用面向对象方法编程,求圆的周长和面积 2024/8/1623 void Circle: Set_Radius( double r ) radius = r ; double Circle: Get_Radius() return radius ; double Circle: Get_Girth() return 2 * 3.14f * radius ; double Circ

19、le: Get_Area() return 3.14f * radius * radius ; 回顾回顾 用面向对象方法编程,求圆的周长和面积用面向对象方法编程,求圆的周长和面积 2024/8/1624void main() Circle A, B ; A.Set_Radius( 6.23 ) ; cout A.Radius = A.Get_Radius() endl ; cout A.Girth = A.Get_Girth() endl ; cout A.Area = A.Get_Area() endl ; B.Set_Radius( 10.5 ) ; cout B.radius = B.G

20、et_Radius() endl ; cout B.Girth= B.Get_Girth() endl ; cout B.Area = B.Get_Area() endl ; 建立对象建立对象(类类型变量)(类类型变量)通过对象通过对象调用类的成员函数调用类的成员函数回顾回顾 用面向对象方法编程,求圆的周长和面积用面向对象方法编程,求圆的周长和面积 2024/8/1625/ 例例 一个类的例子一个类的例子 复数(定义和运算)复数(定义和运算)1.有什么(属性)有什么(属性)2.能干什么(方法)能干什么(方法)2024/8/1626class ComplexdoubleReal,Image ;p

21、ublic :SetComplex(double r, double i) Real=r; Image=i; void Print() coutReal=RealtImage=Imagen; 2024/8/1627/ 例例 一个类的例子一个类的例子 日期(定义和运算)日期(定义和运算)1.有什么(属性)有什么(属性)2.能干什么(方法)能干什么(方法)2024/8/1628/ 例例 一个类的例子一个类的例子class Tdate public: void Set(int m, int d, int y ) month = m ; day = d ; year = y ; int IsLeapY

22、ear() return ( year%4 = 0 & year%100 != 0 | year%400 = 0); void Print() cout year . month . day endl ; private: int month; int day; int year;void main() Tdate a ; a.Set (10, 16, 2003) ; a.Print() ;2024/8/1629数据成员多为私有的,要对它们进行初始化,数据成员多为私有的,要对它们进行初始化,必须用一个公有函数来进行。同时这个函数应该必须用一个公有函数来进行。同时这个函数应该在且仅在定义对象时自

23、动执行一次。称为:在且仅在定义对象时自动执行一次。称为:构造函数构造函数4.3.1构造函数的定义与使用构造函数的定义与使用4.3.2析构函数的定义析构函数的定义与使用与使用构造函数与析构函数 2024/8/1630n构造函数由于类的封装性,不能象普通变量一样初始化。n构造函数的作用是在对象被创建时使用特定的值构造对象,或者说将对象初始化为一个特定的状态。在对象创建时由系统自动调用。n如果程序中未声明,则系统自动产生出一个默认形式的构造函数。n允许为内联函数、重载函数、带默认形参值的函数。构造函数的定义与使用2024/8/16311.函数名与类名相同。函数名与类名相同。2.构构造造函函数数无无函

24、函数数返返回回类类型型说说明明。注注意意是是什什么么也也不不写写,也也不可写不可写void!3.在在程程序序运运行行时时,当当新新的的对对象象被被建建立立,该该对对象象所所属属的的类类的的构构造造函函数数自自动动被被调调用用,在在该该对对象象生生存存期期中中也也只只调用这一次。调用这一次。4.构构造造函函数数可可以以重重载载。严严格格地地讲讲,说说明明中中可可以以有有多多个个构构造造函函数数,它它们们由由不不同同的的参参数数表表区区分分,系系统统在在自自动动调用时按一般函数重载的规则选一个执行。调用时按一般函数重载的规则选一个执行。构造函数的特征2024/8/16325.构造函数可以在类中定义

25、,也可以在类外定义。构造函数可以在类中定义,也可以在类外定义。 6. 如果类说明中没有给出构造函数,则如果类说明中没有给出构造函数,则C+编译器编译器自动给出一个自动给出一个默认默认的构造函数的构造函数: 类名类名( ) 但但只要我们定义了一个构造函数,系统就不会自动只要我们定义了一个构造函数,系统就不会自动生成默认的构造函数生成默认的构造函数。 只要只要构造函数是无参的或各参数均有默认值的构造函数是无参的或各参数均有默认值的,C+编译器编译器都都认为认为是默认的构造函数,是默认的构造函数,并且并且默认的默认的构造函数只能有一个构造函数只能有一个 。 构造函数的特征2024/8/1633析构函

26、数特征:析构函数特征: 当一个对象的生命周期结束时,当一个对象的生命周期结束时,C+C+会自动调用会自动调用析构函析构函数数(destructordestructor)对该对象并进行善后工作,)对该对象并进行善后工作,1.1.构函数名与类名相同,但在前面加上字符构函数名与类名相同,但在前面加上字符 ,如,如CGoodsCGoods()()。2.2.析构函数无函数返回类型,与构造函数在这方面是一样析构函数无函数返回类型,与构造函数在这方面是一样的。但析构函数不带任何参数。的。但析构函数不带任何参数。3. 3. 一个类有一个也只有一个析构函数一个类有一个也只有一个析构函数,这与构造函数不同。这与构

27、造函数不同。析构函数可以默认。析构函数可以默认。4. 4. 对象注销时,系统对象注销时,系统自动调用析构函数自动调用析构函数。析构函数的定义与使用2024/8/1634#include using namespace std;class Q int x,y; public: Q(int a=0,int b=0) cout“调用了构造函数”endl; x=a;y=b; void P(void) coutxtyn; Q() cout“调用了析构函数!”n; void main(void)void main(void) Q q(50,100); Q q(50,100); q.P(); q.P();

28、cout cout“退出主函数退出主函数! !”nn”; ; 输出:输出:调用了构造函数调用了构造函数5050100100退出主函数!退出主函数!调用了析构函数!调用了析构函数!构造函数与析构函数举例 2024/8/1635【例例4.2】矩矩形形类类。要要确确定定一一个个矩矩形形(四四边边都都是是水水平平或或垂垂直直方方向向,不不能能倾倾斜斜),只只要要确确定定其其左左上上角角和和右右下下角角的的x和和y坐坐标即可,即左右上下四个边界值。标即可,即左右上下四个边界值。class Rectangle int left, top, right, bottom;public:Rectangle(in

29、t =0, int =0, int =0, int =0); /默认构造函数必须在此指定默认实参默认构造函数必须在此指定默认实参 Rectangle(); /析构函数,在此函数体为空析构函数,在此函数体为空void Assign(int , int , int , int );void SetLeft(int t) left = t; void SetRight( int t ) right = t;void SetTop( int t ) top = t;void SetBottom( int t ) bottom = t;void Show(); 2024/8/1636#include u

30、sing namespace std;Rectangle:Rectangle(int l , int t, int r, int b) left = l; top = t; right = r; bottom = b; void Rectangle:Assign(int l, int t, int r, int b) left = l; top = t; right = r; bottom = b; void Rectangle:Show() cout”left-top point is (”left”,”top ”)”n; cout”right-bottom point is (”right

31、”,” bottom”)”n; 2024/8/1637#include using namespace std;int main()Rectangle rect; rect.Show();rect.Assign(100,200,300,400);rect.Show();Rectangle rect1(0,0,200,200);rect1.Show();Rectangle rect2(rect1);rect2.Show();return 0;2024/8/1638引用的导入:引用的导入: 参参数数传传递递的的传传值值方方式式在在函函数数域域中中为为参参数数重重新新分分配配内内存存,而而把把实实参

32、参的的数数值值传传递递到到新新分分配配的的内内存存中中。它的优点是它的优点是有效避免函数的副作用有效避免函数的副作用。 问问题题:如如果果要要求求改改变变实实参参的的值值,怎怎么么办办呢呢?如如果果实实参参是是一一个个复复杂杂的的对对象象,重重新新分分配配内内存存会会引引起起程程序执行效率大大下降,怎么办呢序执行效率大大下降,怎么办呢? ? 有有一一种种导导出出型型数数据据类类型型引引用用可可以以解解决决上上面面的的难题。引用又称难题。引用又称别名别名。引用2024/8/1639引用的定义:引用的定义: 引引用用是是给给一一个个已已经经定定义义的的变变量量重重新新起起一一个个别别名名,而不是定

33、义一个新的变量,定义的格式为:而不是定义一个新的变量,定义的格式为:类型类型 &引用变量名引用变量名=已定义过的变量名;已定义过的变量名;例如:例如:double number ;double &newnum=number ;newnum是是新新定定义义的的引引用用类类型型变变量量,它它是是变变量量number的的别名别名。 引用主要用于函数之间的数据传递。引用主要用于函数之间的数据传递。引用2024/8/1640Xyd1d2temp1.4142.7181.4142.7181.414void swap(double & d1, double & d2) double temp ; temp=d

34、1 ; d1=d2 ; d2=temp ; int main(void) double x , y ; cout请输入请输入x和和y的值的值 xy ; swap(x,y) ; coutx=xt y=yn; return 0; 【例例4.3】引用作引用作为函数的参数。为函数的参数。采用引用调用时,将采用引用调用时,将对实参进行操作。对实参进行操作。2024/8/1642同同一一个个类类的的对对象象在在内内存存中中有有完完全全相相同同的的结结构构,如如果果作作为为一一个个整整体体进进行行复复制制是是完完全全可可行行的的。这这个个复复制制过过程程只只需需要要复复制制数数据据成成员员,而而函函数数成成

35、员员是是共共用用的的(只只有有一一份份代代码码)。在在建建立立对对象象时时可可用用同同一一类类的的另另一一个个对对象象来来初初始始化化该该对对象象,这这时所用的构造函数称为时所用的构造函数称为复制(拷贝)构造函数复制(拷贝)构造函数。复制(拷贝)构造函数2024/8/1643 实例:实例:CGood Car1(“夏利夏利2000”,30,98000.00);/调用三个参数的构造函数调用三个参数的构造函数CGood Car2= Car1; /调用复制构造函数调用复制构造函数CGood Car3 ( Car1); /调用复制构造函数,调用复制构造函数,Car1为实参为实参这样三个对象的初始化结果完

36、全一样。这样三个对象的初始化结果完全一样。复制构造函数2024/8/1644n复制构造函数是一种特殊的构造函数,其形参为本类的对象引用。n作用:使用一个对象(参数指定的对象),去初始化一个正在被建立的同类型对象。class 类名 public : 类名(形参);/构造函数 类名(类名 &对象名);/复制构造函数 .;类名: 类名(类名 &对象名)/复制构造函数的实现 函数体 复制构造函数2024/8/1645class Point public: Point(int xx=0,int yy=0)X=xx; Y=yy; Point(Point& p); int GetX() return X;

37、int GetY() return Y; private: int X,Y;Point:Point (Point &p) X=p.X; Y=p.Y; cout“复制构造函数被调用endl;复制构造函数举例2024/8/16461. 复制构造函数的参数必须采用复制构造函数的参数必须采用引用引用。2. 2. 系统会自动提供称为系统会自动提供称为默认的按成员语义支持的默认的按成员语义支持的复制构造函数,亦称为复制构造函数,亦称为默认的按成员默认的按成员初始化初始化。按成员作复制是通过依次复制每个数据成员实按成员作复制是通过依次复制每个数据成员实现的。现的。复制构造函数的特征2024/8/1647(1

38、)当用类的一个对象去初始化该类的另一个对象时系统自动调用复制构造函数实现拷贝赋值。void main(void) Point A(1,2); Point B(A); /复制构造函数被调用coutB.GetX()endl;复制构造函数调用的三种情况2024/8/1648(2)若函数的形参为类对象,调用函数时,实参赋值给形参,系统自动调用复制构造函数。例如:void fun1(Point p) coutp.GetX()endl; void main() Point A(1,2); fun1(A); /调用复制构造函数 复制构造函数调用的三种情况2024/8/1649(3)当函数的返回值是类对象时,

39、系统自动调用复制构造函数。例如:Point fun2() Point A(1,2); return A; /调用复制构造函数void main() Point B; B=fun2(); 复制构造函数调用的三种情况2024/8/1650聚合(聚合(aggregation aggregation ) : 类类中中的的成成员员,除除了了成成员员数数据据和和成成员员函函数数外外,还还有有成成员员对对象象,即即用用其其他他类类的的对对象象作作为为类类的的成成员员。使使用用成成员员对对象象的的技技术术称称为为聚聚合合。成成员员对对象象是是实实体体,系系统统不不仅为它分配内存,而且要进行初始化。仅为它分配内

40、存,而且要进行初始化。成员对象与构造函数2024/8/1651n原则:不仅要负责对本类中的基本类型成员数据赋初值,也要对对象成员初始化。n声明形式:类名:类名(对象成员所需的形参,本类成员形参) :对象1(参数),对象2(参数),. 本类初始化 含对象成员的构造函数2024/8/1652class Point private: float x,y; /点的坐标 public: Point(float xx,float yy); /构造函数 float GetX(void) return x; /取X坐标 float GetY(void) return y;/取Y坐标;类组合构造函数实例2024

41、/8/1653class Line private: /线段的两个端点线段的两个端点 Point p1,p2; double s; public: /构造函数构造函数 Line(Point a,Point b); /如何写?如何写? ;类组合构造函数实例2024/8/1654Line:Line(Point a,Point b):p1(a),p2(b) double x=double(p1.GetX()-p2.GetX(); double y=double(p1.GetY()-p2.GetY(); double dist=sqrt(x*x+y*y); s=dist; 类组合构造函数实例2024/

42、8/1655 含对象成员的析构函数:含对象成员的析构函数: 因为析构函数没有参数,所以包含成员对象的因为析构函数没有参数,所以包含成员对象的类的析构函数形式上并无特殊之处。但是撤销该类的析构函数形式上并无特殊之处。但是撤销该类对象时,会首先调用自己的析构函数,再调用类对象时,会首先调用自己的析构函数,再调用成员对象的析构函数,调用次序与初始化时的次成员对象的析构函数,调用次序与初始化时的次序相反。序相反。成员对象与构造函数2024/8/1656构造函数另一格式:构造函数另一格式:对于不含对象成员的类对象的初始化,也可以套用对于不含对象成员的类对象的初始化,也可以套用以上的格式,把部分需要直接赋

43、初值的变量初始化以上的格式,把部分需要直接赋初值的变量初始化写在冒号的右边:写在冒号的右边:类名类名:构造函数名构造函数名(参数表参数表):变量变量1(初值初值1),变变量量n(初值初值n)当然也可以把一部分变量重新放回花括号中的函数当然也可以把一部分变量重新放回花括号中的函数体。体。冒号以后部分实际是函数体的一部分冒号以后部分实际是函数体的一部分,所以在,所以在构造函数的声明中,冒号及冒号以后部分必须略去。构造函数的声明中,冒号及冒号以后部分必须略去。成员对象与构造函数2024/8/1657构造函数和析构函数的调用规则:构造函数和析构函数的调用规则:1. 对对全全局局定定义义的的对对象象,当

44、当程程序序进进入入入入口口函函数数main之之前前对象就已经定义,整个程序结束时调用析构函数。对象就已经定义,整个程序结束时调用析构函数。2. 对对于于局局部部定定义义的的对对象象,每每当当程程序序控控制制流流到到达达该该对对象象定定义义处处时时,调调用用构构造造函函数数。当当程程序序控控制制走走出出该该局局部部域域时,则调用析构函数。时,则调用析构函数。3. 对对于于静静态态局局部部定定义义的的对对象象,在在程程序序控控制制首首次次到到达达该该对对象象定定义义处处时时,调调用用构构造造函函数数。当当整整个个程程序序结结束束时时调调用析构函数。用析构函数。成员对象与构造函数2024/8/165

45、8运算符重载的概念:运算符重载的概念:运运算算符符的的重重载载是是特特殊殊的的函函数数重重载载,必必须须定定义义一一个个函函数数,并并通通知知C+C+编编译译器器,当当遇遇到到该该重重载载的的运运算算符符时时调调用用此此函函数数。这这个个函函数数叫叫做做运运算算符符重重载载函函数数,通通常常为为类类的成员函数。的成员函数。运算符重载函数定义:运算符重载函数定义:返回值类型返回值类型 类名类名:operatoroperator重载的运算符重载的运算符( (参数表参数表) ) operatoroperator是关键字,它与重载的运算符一起构成函数是关键字,它与重载的运算符一起构成函数名。名。因函数

46、名的特殊性,因函数名的特殊性,C+C+编译器可以将这类函数识编译器可以将这类函数识别出来。别出来。运算符的重载2024/8/1659n运算符重载是对已有的运算符赋予多重含义n必要性uC+中预定义的运算符其运算对象只能是基本数据类型,而不适用于用户自定义类型(如类)n实现机制u将指定的运算表达式转化为对运算符函数的调用,运算对象转化为运算符函数的实参。u编译系统对重载运算符的选择,遵循函数重载的选择原则。运算符重载的实质2024/8/1660n重载为类成员函数。运算符重载的形式n重载为类成员函数时 参数个数=原操作数个数-1(后置+、-除外)2024/8/1661 运算符函数是一种特殊的成员函数

47、或友员函数运算符函数是一种特殊的成员函数或友员函数 成员函数的语法形式为:成员函数的语法形式为:类型类型 类名类名 : operatoroperator opop ( ( 参数表参数表 ) ) / / 相对于该类定义的操作相对于该类定义的操作 运算符要求的操作数运算符要求的操作数一个一个运算符被重载后,原有意义没有失去,只是运算符被重载后,原有意义没有失去,只是定义了相对一特定类的一个新运算符定义了相对一特定类的一个新运算符2024/8/1662class ComplexdoubleReal,Image ;public :Complex(double r=0.0, double i=0.0):

48、Real(r),Image(i) Complex(Complex &com)Real=com.Real ; Image=com.Image ; void Print()coutReal=RealtImage=Imagen; Complex operator+(Complex); /重载重载+运算符函数运算符函数Complex operator+(double); /重载重载+运算符函数运算符函数 ; 【例例4.84.8】复数类,应用它进行复数运算复数类,应用它进行复数运算2024/8/1663Complex Complex:operator+(double d) /重载重载+ return C

49、omplex(Real+d , Image); Complex Complex:operator+(Complex c)/重载重载+ Complex Temp(Real+c.Real , Image+c.Image) ;return Temp ; 2024/8/1664int main(void)Complex c1(1.0,1.0) , c2(2.0,2.0) , c3(4.0,4.0) , c;double d=0.5 ;c1.Print();c=c2+c3 ; c.Print() ;c=c+d ; c.Print() ; /可用可用0.5代替代替dreturn 0; 2024/8/166

50、5运算符的重载n引用作为参数: Complex Complex:operator+(const Complex &c) return Complex(real+c.real , Image+c.Image) ; 2024/8/1666 由由关关键键字字static修修饰饰说说明明的的类类成成员员,成成 为为 静静 态态 类类 成成 员员 ( static class member)。但但与与函函数数中中的的静静态态变变量量有有明明显显差差异异。类类的的静静态态成成员员为为其其所所有有对对象象共共享享,不不管管有有多多少少对对象象,静静态态成成员员只只有有一份存于公用内存中。一份存于公用内存中。

51、静态成员2024/8/1667静态数据静态数据成员定义与使用:静态数据成员定义与使用:在类定义中,用关键字在类定义中,用关键字static修饰的数据成员为修饰的数据成员为静态数静态数据成员据成员。静态数据成员静态数据成员属于整个类属于整个类,使用使用时可用以下时可用以下格式格式:类名类名:静态数据成员名静态数据成员名2024/8/1668n全局对象不安全,如何解决?n使用类中的静态数据成员解决访问权限问题。 classemployeeprivate:intEmpNo;intID;charsex;静态数据如:需要统计雇员如:需要统计雇员总数,数据存放在总数,数据存放在什么地方?什么地方?2024

52、/8/1669n一个类的所有对象具有相同的属性;n类属性:描述类的所有对象的共同特征的一个数据项,对于任何对象实例,它的属性值是相同的;n静态数据成员q用关键字static声明q该类的所有对象维护该成员的同一个拷贝;q必须在类外定义和初始化,用(:)来指明所属的类。静态数据2024/8/1670具有静态数据成员的 Point类#include using namespace std;class Pointpublic:Point(int xx=0, int yy=0) X=xx; Y=yy; countP+; Point(Point &p);int GetX() return X;int Ge

53、tY() return Y;void GetC() cout Object id=countPendl;private:int X,Y;static int countP;2024/8/1671Point:Point(Point &p)X=p.X;Y=p.Y;countP+;int Point:countP=0; void main() Point A(4,5); /分配空间coutPoint A,A.GetX(),A.GetY();A.GetC(); Point B(A); /分配空间coutPoint B,B.GetX(),B.GetY();B.GetC(); A.GetC();2024/

54、8/1672【例例4.94.9】用静态数据成员计算由同一类建立的对象的数量用静态数据成员计算由同一类建立的对象的数量class Ctestprivate: static int count;/注意私有注意私有public: Ctest() +count;cout对象数量对象数量=countn; Ctest() -count;cout对象数对象数=countn; ;int Ctest:count=0; /A行行 对静态数据定义性说明对静态数据定义性说明int main(void) Ctest a3; return 0;执行程序后输出:执行程序后输出:对象数量对象数量=1 /a0=1 /a0构造函数产生构造函数产生对象数量对象数量=2 /a1=2 /a1构造函数产生构造函数产生对象数量对象数量=3 /a2=3 /a2构造函数产生构造函数产生对象数量对象数量=2 /a2=2 /a2析构函数产生析构函数产生对象数量对象数量=1 /a1=1 /a1析构函数产生析构函数产生对象数量对象数量=0 /a0=0 /a0析构函数产生析构函数产生2024/8/1673本章小结n面向对象的基本概念n类的定义n构造函数 析构函数 复制构造函数n静态数据

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 高等教育 > 研究生课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号