c++1类与对象ppt

上传人:sx****84 文档编号:242967621 上传时间:2024-09-13 格式:PPT 页数:168 大小:335KB
返回 下载 相关 举报
c++1类与对象ppt_第1页
第1页 / 共168页
c++1类与对象ppt_第2页
第2页 / 共168页
c++1类与对象ppt_第3页
第3页 / 共168页
点击查看更多>>
资源描述
单击此处编辑母版标题样式,*,*,回顾与分析,结构化程序设计,求圆的面积问题,学生成绩问题,结构化程序设计:,1,)支持三种基本语句结构;,2,)支持自顶向下、逐步求精、模块化程序设计方法,=,数据(结构),+,操作(算法),核心,1,结构化程序设计的优点与缺陷,(,1,)优点,整体思路清楚,目标明确。设计工作中阶段性非常强,有利于系统开发的总体管理和控制。在系统分析时可以诊断出原系统中存在的问题和结构上的缺陷。,(,2,)缺点,对较复杂系统,难以控制,用户要求难以在系统分析阶段准确定义,致使系统在交付使用时产生许多问题。系统的可扩展性较差。不能适应事物变化的要求。软件的可重用性差。,2,课程总体安排,理论:32学时,实验:24学时,3,第,1,章,类和对象,重点掌握内容:,面向对象程序设计的基本特点,类和对象的定义和使用,类的设计基本方法,2024/9/13,4,第,1,章 类和对象,1.1,面向对象程序设计概述,1.2,面向对象方法的基本特征,1.3,类和对象的定义,1.4,类的成员函数,1.5,对象成员的引用,2024/9/13,5,1.1,面向对象程序设计概述,一、什么是面向对象程序设计,面向对象程序设计(,Object Oriented Programming-,简称,OOP,)是软件系统设计与实现的新方法,这种新方法即吸取了结构化程序设计的全部优点,又考虑了现实世界与面向对象空间的映射关系,所追求的目标是将现实世界的问题求解尽可能的简单化。,二、面向对象程序设计的基本思路,2024/9/13,6,1.2,面向对象方法的基本特征,1.2.1,对象和类,1.2.2,封装(,encapsulation,)与数据隐藏,1.2.3,继承(,inheritance,)与重用,1.2.4,多态性(,polymorphism,),1.2.5,消息,1.2.6,面向过程与面向对象程序设计方法的比较,2024/9/13,7,1.2.1,对象和类,一、现实世界与面向对象系统对应关系,2024/9/13,8,1.2.1,对象和类,二、什么是类(,class,),1.,类是一种复杂的数据类型,它将不同类型的数据和与这些数据相关的操作封装在一起。类是对现实世界客观事物的抽象。,2.,两方面的要素:,属性(,atrribute,),-,数据,行为,(behavior),-,数据的操作,(函数),三、什么是对象(,object,),对象是类的一个实体,又称为实例,2024/9/13,9,1.2.1,对象和类,四、对象与类的关系,人类,姓名,年龄,身高,体重,走路,学习,说话,开车,数据抽象,小王,小李,小张,人类,的对象,2024/9/13,10,1.2.1,对象和类,五、对象与对象之间消息传递,对象,1,对象,2,对象,3,对象,4,消息,消息,2024/9/13,11,1.2.2,封装与数据隐藏,一、什么是封装,(,encapsulation,),封装是指将对象的数据和与这个数据有关的操作放在一起。,各个对象之间相互独立,互不干扰。,对象只留少量的接口,以便与外部联系。从外部看对象就像一个,“,黑匣子,”,,数据和方法是隐蔽的、看不见的。,当用户使用对象时,不必知道对象的具体实现细节,只需要根据对象提供的外部接口访问对象即可。,2024/9/13,12,1.2.2,封装与数据隐藏,二、封装应具有以下几个特点,具有一个清楚的边界,私有成员封装在内部,外部不可以访问,提供必要的接口,对象内部的数据和方法是受封装外壳保护的,其它对象不能直接使用。,主机,主板,显卡,声卡,内存,数据传输线,电源线,USB,接口,串行接口,电源开关,内,部,私,有,成,员,与,外,部,接,口,2024/9/13,13,1.2.3,继承与重用,一、继承,(,inheritance,),概念的提出,例如:已定义电视机类,现需要定义彩色电视机类,解决方法:,1.,重新设计,2.,继承:继承原来电视机的属性和方法,再添加彩色电视机自己特有的新的属性和行为,2024/9/13,14,1.2.3,继承与重用,二、继承的概念,C+,提供的继承机制提供了类之间相互关系的解决方案,使某个类可以继承另外一个类的特征和能力。,使用继承符合人们对事物的认识和叙述,大大简化了对问题的描述,提高了程序的可重用性,从而提高了程序设计、修改、扩充的效率,实现软件重用(,software reusability,)。,2024/9/13,15,1.2.4,多态性(,polymorphism,),一、多态性的概念,多态性:描述的是同一个消息可以根据发送消息对象的不同采用不同的行为方式。,例如,:,学校的上课铃响,不同班级的学生进入不同的教室学习,不同的老师进入不同教室开始讲课,不同的对象会作出不同的响应。可以看到学生和教师在接受到同一消息(上课铃声)时,执行不同的操作,这就是多态的表现。,2024/9/13,16,1.2.4,多态性(,polymorphism,),二、,C+,支持多态,在,c,+,程序设计中,,多态性是指具有不同功能的函数可以用同一个函数名,这样就可以用同一个函数名调用不同内容的函数,或指发出同样的消息被不同类型的对象接收时产生不同的执行结果和行为。,2024/9/13,17,1.2.5,消息,面向对象技术的封装使得对象相互独立,各个对象要相互协作实现系统的功能则需要对象之间的消息传递机制。消息是一个对象向另一个对象发出的服务请求,进行对象之间的通信。也可以说是一个对象调用另一个对象的方法(,Method,)或称为函数(,Function,)。,2024/9/13,18,1.2.6,面向过程与面向对象程序设计方法的比较,一、面向过程程序设计方法,程序,=,数据结构,+,算法,二、面向对象程序设计方法的规律是:,对象,=,(数据结构,+,算法),程序,=,对象,+,对象,+,对象,+,+,对象,2024/9/13,19,1.3.1,类的定义,一、类定义组成,数据成员:说明类的属性,成员函数(又称函数成员):对类数据成员操作的类内函数,又称为方法。,二、类定义的一般格式:,class,类名,public :,数据成员和成员函数实现,protected/private :,数据成员和成员函数实现,;,2024/9/13,20,1.3.1,类的定义,说明:,1,)定义一个类时,使用关键字,class,;类名必须是一个合法的变量名,;,2,)一个类包括类头和类体两部分。,3,)大括号中定义的是类的数据成员和成员函数,称为类体(,class body,)。类定义结束要用,“,;,”,结束;,4,)关键字,public,、,protected,和,private,称为成员访问限定符。用访问限定符声明了各个数据成员和成员函数的访问权限,2024/9/13,21,1.3.1,类的定义,三、访问限定符,公有(,public,):提供了与外界的接口功能。公有成员可以被本类中的成员使用和访问,还可以被类作用域内的其他外在其他函数使用。,私有(,private,):封装在类内部的,只能被该类的成员和该类友元函数或友元类访问,任何类以外的函数对私有成员的访问都是非法的。,保护(,protected,):访问权限介于私有和公有中间,类的成员可以访问,类以外的其他函数不能访问保护成员,2024/9/13,22,1.3.1,类的定义,类,A,class,外部,私有成员,private,保护成员,protected,公有成员,public,继承类,友元,class,外部,2024/9/13,23,1.3.1,类的定义,例:定义一个日期类,Cdate,Cdate,year : int,month :int,day : int,Setdate (y : int, m : int, d : int),Isleapyear() :,Print(),2024/9/13,24,class Cdate /,声明一个类,类名为,Cdate,public: /,以下是公有成员函数,void,Setdate,(int y, int m,int d)/,设置日期,year=y;,month=m;,day=d;,/,以上,3,行是函数的实现,2024/9/13,25,int,Isleapyear,(),return (year%4=0,void,Print,(),coutyear- month -dayendl;,private:,int,year,month ,day,;,;,2024/9/13,26,1.3.2,类对象的定义,1,先声明类类型,然后定义类的对象, class ,类名 对象列表;,说明:,1,),class,可选,可以写,也可以省略,2,)类名要符合标识符的命名规则。,3,)对象列表的格式为:对象名,,对象名,对象名,。定义多个对象时,各对象名中间用逗号隔开,class Cdate,date1,date2,date3; /Cdate,是类类型,Cdate,date1,date2,date3; /,建议使用的方法。,2024/9/13,27,2,在声明类类型的同时定义对象,class,类名,数据成员和成员函数实现,对象列表,;,3,不写类名,直接定义类对象,class,数据成员和成员函数实现,对象列表;,1.3.2,类对象的定义,2024/9/13,28,1.3.3,类对象的内存分配,C+,中用同一内存空间来存放这个同种类对象的成员函数代码,当去调用某个对象的成员函数时,都去调用这个公用的函数代码。,C+,中用,this,指针来区分是哪个对象的成员函数。,数据成员,对象,1,数据,成员,对象,2,数据,成员,对象,n,公用成员函数代码,2024/9/13,29,1.4,类的成员函数,类的成员函数也是函数的一种,它的与以前介绍的普通函数用法基本一样。,成员函数由函数头和函数体组成,函数头包括函数名、函数的参数及函数的类型。函数体主要,说明,函数实现的功能。,2024/9/13,30,1.4,类的成员函数,成员函数与一般函数的区别在于:它属于类的成员,出现在类体中,是类的一部分。使用类的成员函数时,要考虑类成员函数的访问权限。,类的成员函数可以在类体中定义,也可以在类体中声明类成员函数,成员函数的实现在类外定义。,2024/9/13,31,1.4.1,在类内定义成员函数,#include ,class Cdate,public:,void,Setdate,(int y, int m,int d),/,在类内定义成员函数,year=y;,month=m;,day=d;,2024/9/13,32,1.4.1,在类内定义成员函数,int,Isleapyear,(), return (year%4=0&year%100!=0),|(year%400=0);,void,Print,(), coutyear- month -dayendl;,private:,int,year,month ,day;,;,2024/9/13,33,1.4.2,在类外定义成员函数,说明:,在类内定义的成员函数默认的是内联函数(,inline,函数)。一般把规模比较小的成员函数在类内定义。,通常情况下,C+,程序员习惯在类体中只定义数据成员以及成员函数的声明,而将成员函数的实现写在类外。因此类的定义由声明部分和实现部分组成。,声明部分:声明类的数据成员类型和成员函数的参数类型、个数以及返回值类型。,实现部分:对说明类成员函数的具体实现,2024/9/13,34,1.4.2,在类外定义成员函数,一、定义的格式,class,类名,数据成员类型 数据成员名;,函数类型 成员函数名(参数表),;,;,2024/9/13,35,1.4.2,在类外定义成员函数,/,类实现部分,函数类型 类名:员函数名,1,(参数表),/,实现,函数类型 类名:员函数名,1,(参数表),/,实现,2024/9/13,36,1.4.2,在类外定义成员函数,说明:,(,1,)在类声明部分,包括数据成员的定义和成员函数的声明。,(,2,)成员函数的声明主要说明函数的类型,函数的参数个数及类型,并用,“,;,”,结束。,(,3,)函数实现部分是对在类中定义的成员函数完成功能的实现,包括函数头和函数体。在类体中直接定义函数时,不需要在函数名前面加上类名,因为函数属于哪一个类是不言而喻的。,但成员函数在类外定义时,必须在函数名前面加上类名,给与限定,2024/9/13,37,1.4.2,在类外定义成员函数,(4),“,”,是作用域限定符或称作用域运算符,用它声明函数是属于哪个类的。如果在作用域运算符,“,”,的前面没有类名,或者函数名前面既无类名又无作用域运算符,“,”,,则表示函数不属于任何类,该函数不是成员函数,而是全局函数,即非成员函数的一般普通函数。,2024/9/13,38,1.4.2,在类外定义成员函数,例:,Cdate,类定义,class Cdate,public: /,函数声明,void Setdate (int y, int m,int d);,int Isleapyear();,void Print();,private:,int year,month ,day;,;,2024/9/13,39,1.4.2,在类外定义成员函数,/ Cdate,类成员函数的实现,void Cdate: Setdate (int y, int m,int d),year=y;,month=m;,day=d;,2024/9/13,40,1.4.2,在类外定义成员函数,int Cdate:Isleapyear(),return (year%4=0&year%100!=0)|,(year%400=0);,void Cdate:Print(),coutyear- month -day,数据成员名,/,“,-,”,是指向运算符,对象指针名,-,成员函数名,例如:,Cdate d,*p; /,定义对象,d,和对象指针变量,p,p= /,初始化对象指针,p,p-Print();/,通过指向对象的指针和指向运算符访问对象中的成员,2024/9/13,44,1.5,对象成员的引用,(,3,)通过对象的引用变量访问对象中的成员,如果为一个对象定义了一个引用变量,它们是共占同一段存储单元的,因此可以通过引用变量来访问该对象中的成员。,例如:,Cdate d1; /,定义对象,d1,Cdate/,定义引用变量,d2,d2. Print(); /,引用变量访问对象中的成员,2024/9/13,45,/ Cdate.h,在头文件中声明日期类,class Cdate,public:,void Setdate (int y, int m,int d);,int Isleapyear();,void Print();,private:,int year,month ,day;,;,【,例,1.1】,一个完整的,Cdate,类的应用程序,2024/9/13,46,/Cdate.cpp,定义成员函数实现部分,#include ,#include,“,Cdate.h,”,/,包含类定义的头文件,void Cdate: Setdate (int y, int m,int d),year=y; month=m; day=d;,int Cdate:Isleapyear(), return (year%4=0&year%100!=0)|,(year%400=0);,void Cdate:Print(), coutyear- month -day Setdate(2000,4,2); /,通过指针访问成员,d4. Setdate(2006,12,1); /,通过引用访问成员,d1.Print(); p- Print(); d4.Print();,2024/9/13,48,【,例,1.2】,封装一个学生类,学生的信息包括学生的姓名、学号、性别、年龄和,3,门的成绩。可以设置学生的各类信息,统计该学生的平均成绩并输出学生信息。,CStudent,name20 : char id : int,sex : char age : int,grad3 : float,setinfo(na : char *,i : int ,s : char, a : int) : void,void setgrad(a : float , b : float , c : float) : void,avg() : float +display() : void,Cstudent,的类图,2024/9/13,49,/CStudent.h,这是头文件,在此文件中进行类的声明,class CStudent /,类声明,public:,void setinfo(char *,int ,char,int);,void setgrad(float , float , float);,float avg();,void display();,private:,char name20;,int id ;,char sex;,int age;,float grad3;,;,2024/9/13,50,/CStudent.cpp,在此文件中进行函数的定义,#include ,#include ,#include CStudent.h/,漏写此行编译通不过,void CStudent:setinfo(char *na,int i ,char s ,int a),strcpy(name,na);,id=i;,sex=s; age=a;,void CStudent:setgrad(float a, float b, float c),grad0=a; grad1=b; grad2=c;,2024/9/13,51,float CStudent:avg(),return (grad0+ grad1 +grad2)/3;,void CStudent:display( ),coutid:idendl;,coutname:nameendl;,coutsex:sexendl;,coutage:ageendl;,2024/9/13,52,/main.cpp,主函数模块,#include ,#include CStudent.h/,将类声明头文件包含进来,void main( ),CStudent stud1;/,定义对象,stud1. setinfo(,张三,2006102,m,18);,stud1.setgrad(79,98,87);,stud1.display();,cout ,平均成绩:,stud1.avg();,2024/9/13,53,1.6,构造函数和析构函数,构造函数和析构函数的作用,1.,构造(,constructor,)函数,在创建对象时,系统自动调用它来初始化数据成员;,2.,析构(,destructor,)函数,在对象生存期结束的时候,自动调用来释放该对象。,2024/9/13,54,1.6.1,构造函数的定义,一、构造函数的定义格式:,class,类名,public,:,构造函数函数名(参数表);,;,2024/9/13,55,1.6.1,构造函数的定义,二、构造函数的特点,(,1,)构造函数是类的一个特殊的成员函数,函数名与类名相同;,(,2,)构造函数的访问属性应该是公有(,public,)访问属性;,(,3,)构造函数的功能是对对象进行初始化,因此在构造函数中只能对数据成员做初始化,这些数据成员一般为私有成员,在构造函数中一般不做初始化以外的事情;,2024/9/13,56,1.6.1,构造函数的定义,(,4,)构造函数可以在类内定义也可以在类外定义;,(,5,)构造函数无函数返回类型。注意:是什么也不写,也不可写,void,;,(,6,)在程序运行时,当新的对象被建立,该对象所属的类的构造函数自动被调用,在该对象生存期中也只调用这一次。,(,7,)构造函数可以重载。类中可以有多个构造函数,它们由不同的参数表区分,系统在自动调用时按一般函数重载的规则选一个执行。,2024/9/13,57,【,例,1.3】,定义,Cdate,一个不带参数的构造函数。,#include ,class Cdate/,定义,一个,日期类,public:/,公有数据成员,Cdate()/,定义构造函数,year=2000;/,初始化数据成员,month=1;,day=1;,2024/9/13,58,void Print()/,一般成员函数, coutyear- month -dayendl; ,private:,int year, month ,day;,;,void main(),Cdate d1;,/,自动调用构造函数,d1.Print();,2024/9/13,59,【,例,1.4】Cdate,类带参数的构造函数,#include ,class Cdate,public:,Cdate(int y, int m,int d);,void Print();,private:,int year,month ,day;,;,Cdate:Cdate(int y, int m,int d),year=y; month=m; day=d;,2024/9/13,60,void Cdate:Print(),coutyear- month -dayendl;,void main(),Cdate,d1(1999,12,30);,Cdate d2(2001,4,1);,d1.Print();,d2.Print();,2024/9/13,61,三、使用初始化表来实现对数据成员的初始化,初始化表的一般格式:,类名,:,构造函数名,(,参数列表,):,初始化表,构造函数其他实现代码,初始化表的格式:,对象成员,1(,参数名或常量,),,对象成员,2(,参数名或常量,),,,对象成员,n(,参数名或常量,),2024/9/13,62,三、使用初始化表来实现对数据成员的初始化,例如例,1.4,定义的构造函数可以改用以下形式:,Cdate:Cdate(int y, int m,,,int d):year(y), month(m),day(d) ,注意:,这种写法方便、简洁。许多,C+,程序员喜欢用这种方式初始化所有的数据成员。除了构造函数可以使用初始化表外,类的其他成员函数也可以根据需要使用初始化表。,2024/9/13,63,1.6.2,构造函数的重载,程序中需要以不同的方式初始化类对象时,,可以在一个类中定义多个构造函数,即可以重载构造函数,。,C+,定义对象时,根据声明中的参数个数和类型选择相应的构造函数初始化对象。,2024/9/13,64,【,例,1.5】Cdate,类中的重载构造函数,#include ,class Cdate,public:,Cdate();/,不带参数的构造函数,又称默认构造函数,Cdate(int y);/,带,1,个参数的构造函数,Cdate(int y, int m); /,带,2,个参数的构造函数,Cdate(int y, int m,int d); /,带,3,个参数的构造函数,void Print();,private:,int year,month ,day;,;,2024/9/13,65,Cdate: Cdate()/,构造函数的定义, year=2000; month=1; day=1;,Cdate: Cdate(int y), year=y; month=1; day=1;,Cdate: Cdate(int y, int m), year=y; month=m; day=1;,Cdate: Cdate(int y, int m,int d), year=y; month=m; day=d;,2024/9/13,66,void Cdate:Print(),coutyear-month-dayendl;,void main(),Cdate day1; Cdate day2(2004);,Cdate day3(2005,2); Cdate day4(2006,12,16);,day1.Print(); day2.Print();,day3.Print(); day4.Print();,2024/9/13,67,1.6.2,构造函数的重载,关于构造函数,C+,规定:,(,1,),每个类必须有一个构造函数,,如果没有就不能创建任何对象;,(,2,),若没有定义任何一个构造函数,,C+,提供一个默认的构造函数,该构造函数没有参数,不做任何工作,相当一个空函数,,例如:,Cdate:Cdate,(),2024/9/13,68,1.6.2,构造函数的重载,所以在讲构造函数以前也可以定义一个对象,就是因为系统提供的默认构造函数。,(,3,)只要,C+,提供一个构造函数(不一定是没有参数的),,C+,不再提供默认的构造函数。也就是说为类定义了一个带参数的构造函数,还想要创建无参的对象时,则需要自己定义一个默认构造函数,2024/9/13,69,1.6.3,默认参数的构造函数,为什么使用默认参数的构造函数:,对象常有一些初始值,。,【,例,1.6】,设计,CPoint,类,它带有默认参数的构造函数。,分析:,一个点包括横坐标(,x,)和纵坐标(,y,)两个数据成员,默认初始值为(,0,0,),。也可以根据用户需要,初始化点为其他坐标,因此需要定义一个带默认参数的构造函数。定义成员函数,print(),输出该点。,2024/9/13,70,CPoint,/,数据成员,x : double,y : double,/,函数成员,CPoint(x1 : double,=0,y1 : double,=0,),;,/ /,默认参数构造成员,Void print(),;,2024/9/13,71,#include ,class CPoint,public:,CPoint (double x1=0,double y1=0), x=x1; y=y1; ,void print (),cout(x,y)endl;,private:,double x,y;,;,2024/9/13,72,void main(),CPoint point1; /,自动调用带默认参数的构造函数,CPoint point2(10);/,自动调用带默认参数的构造函数,CPoint point3(20,30);/,自动调用构造函数,point1.print();,point2.print();,point3.print();,注意:,构造函数是对象创建时自动调用的,不能显式调用。,2024/9/13,73,一个类可以包括多个构造函数,但对每一个对象来说,对象创建时只能执行其中一个与对象参数相匹配的构造函数。下面代码存在二义性问题:,#include ,class CPoint,public:,/,带默认参数的构造函数,CPoint (double x1=0,double y1=0), x=x1; y=y1; ,/,带一个参数的构造函数,CPoint (double x1), x=x1; y=100; ,2024/9/13,74,/,其他成员函数,private:,double x,y;,;,void main(),CPoint point1(10);,/,错误,匹配哪个构造函数不确定,point1.print();,2024/9/13,75,1.6.4,析构函数,一、析构函数的作用,析构函数是一个特殊类成员函数,它的作用与构造函数相反。,析构函数的作用是在对象生存期结束之前自动执行,做清理工作。,例如:,一个类可能在构造函数中分配资源,这些资源要在对象的生存期结束以前释放,释放资源的工作就是自动调用类的析构函数完成的。,2024/9/13,76,1.6.4,析构函数,二、析构函数的特点,(,1,)析构函数函数的名字特别,是类名加,“,”,字符,表明它与构造函数相反;,(,2,),析构函数没有参数,不能指定返回值类型,;,(,3,),一个类中只能定义一个析构函数,所以析构函数不能重载,;,(,4,),在对象生存期结束时,系统自动调用析构函数,。,2024/9/13,77,1.6.4,析构函数,三、析构函数的定义格式,类名,:,析构函数名(),/,实现代码,例如:,Cdate,:,Cdate,(),2024/9/13,78,【,例,1.7】,设计一个简单的字符串类,CString,,类中有两个数据成员,分别表示字符串的长度和字符串的内容。定义一个构造函数和一个析构函数,成员函数,GetLength( ),返回字符串长度,成员函数,GetContents( ),获得字符串的内容,重载成员函数,SetContents( ),可以改变字符串的值。,2024/9/13,79,CString,length : int,contents : char*,CString(),CString(s : char*),CString(),GetLength() : int,GetContents(str : char *),SetContents(len : int, cont : char*),SetContents(cont : char*),2024/9/13,80,#include ,#include ,class CString,public:,CString(); /,默认构造函数,CString(char *s);/,带参数的构造函数,CString(); /,析构函数,int GetLength();/,得到字符串的长度,void GetContents(char *str);/,得到字符串的内容,void SetContents(int len, char *cont);/,重新设置字符串,void SetContents(char *cont); /,重载成员,SetContents,(),重新设置字符串,2024/9/13,81,private:,int length; /,字符串长度,char *contents;/,字符串内容,;,CString:CString(),length = 0; contents = NULL;,cout ,字符串对象初始化:默认构造函数, endl;,CString:CString(char *s),length = strlen(s);,contents = new charlength+1;,strcpy(contents,s);,cout ,字符串对象初始化:一个参数的构造函数, endl;,2024/9/13,82,CString:CString(),cout contents ,被销毁, endl;,if(contents != NULL) delete contents;,int CString:GetLength(),return length;,void CString:GetContents(char *str),strcpy(str, contents);,2024/9/13,83,void CString:SetContents(int len, char *cont),length = len;,if(contents != NULL),delete contents;,contents = new charlen+1;,strncpy(contents,cont,length);,contents length=0;,cout ,两个参数的,SetContents,函数, endl;,2024/9/13,84,void CString:SetContents( char *cont),length = strlen(cont);,if(contents != NULL),delete contents;,contents = new charlength+1;,strcpy(contents,cont);,cout ,一个参数的,SetContents,函数, endl;,void main(),CString str1,str2;,CString str3(,第三个字符串,);,str1.SetContents(,第一个字符串,);,str2.SetContents(20, ,第二个字符串两个参数,2024/9/13,85,int i = str1.GetLength();,char string100;,str1.GetContents(string);,cout i string endl;,i = str2.GetLength();,str2.GetContents(string);,cout i string endl;,i = str3.GetLength();,str3.GetContents(string);,cout i string endl;,2024/9/13,86,1.6.4,析构函数,四、构造函数和析构函数的调用时间和调用顺序,构造函数在创建对象时自动调用,调用的顺序是按照对象定义的次序。,析构函数的调用顺序正好与构造函数相反。也就是说对于同一存储类别的对象是先构造的对象后析构,后构造的对象先析构。,2024/9/13,87,1.6.5,拷贝构造函数和默认拷贝构造函数,一、拷贝构造函数的作用,用一个已知的对象来初始化另一个对象,二、拷贝构造函数定义格式,类名:拷贝构造函数名(类名,&,引用名),例如:,Tdate :Tdate(Tdate /,形参是一个对象的引用,CString( const CString /,形参是一个,const,的对象引用,2024/9/13,88,1.6.5,拷贝构造函数和默认拷贝构造函数,三、通常在下述三种情况下,需要用拷贝初始化构造函数:,(,1,)明确表示由一个对象初始化另一个对象时;如,Cdate day3(d1);,(,2,)当对象作为函数实参传递给函数形参时;如,fun(Cdate day);,(,3,)当对象作为函数的返回值,创建一个临时对象时。,2024/9/13,89,【,例,1.8】,设计一个复数类,两个数据成员分别表示复数的实部(,real,)和虚部(,imag,),有,2,个构造函数分别在不同的情况下初始化对象,函数,Print,()用于输出复数,。,#include ,class CComplex,public:,CComplex(double, double);,CComplex(CComplex ,CComplex add(CComplex ,void Print();,private:,double real, imag;,;,2024/9/13,90,CComplex:CComplex(double r=0.0, double i=0.0),real = r; imag = i;,cout,调用两个参数的构造函数,endl;,CComplex:CComplex (CComplex &c),real = c.real; imag = c.imag;,cout,调用拷贝构造函数,endl;,2024/9/13,91,void CComplex:Print()/,显示复数值, cout ( real , imag ) endl; ,void f(CComplex n) /,对象作为函数参数,coutn=;,n. Print();,CComplex CComplex:add(CComplex & x),CComplex y(real+x.real ,imag+x.imag );,return y; /,调用复数类的拷贝构造函数,2024/9/13,92,void main(void),CComplex a(3.0,4.0), b(5.6,7.9);,CComplex c(a); /,调用复数类的拷贝构造函数,cout a = ;,a.Print();,cout c = ;,c.Print();,f(b); /,对象作为函数实参传递给函数形参,c=a.add(b); /,对象作为函数返回值,调用拷贝构造函数,c.Print ();,2024/9/13,93,调用拷贝构造函数各对象数据成员变化,2024/9/13,94,1.6.5,拷贝构造函数和默认拷贝构造函数,当用户自定义了拷贝构造函数,所用一个对象创建另一个对象时,系统自动调用了用户自定义拷贝构造函数。如果用户没有自己定义拷贝构造函数,那么编译系统会自动会提供一个默认的拷贝构造函数。,四、默认拷贝构造函数,默认的拷贝构造函数所做的工作是将一个对象的全部数据成员赋值另一个对象的数据成员。,C+,把这种只进行对象数据成员简单赋值,称之为“浅拷贝”,2024/9/13,95,【,例,1.9】,设计一个班级类,CClass,,两个数据成员,name,和,num,分别表示班级的名称和人数。函数,Print,()输出班级名称和班级人数。,class CClass,public:,CClass (char *cName=,int snum=0);, CClass (),cout,析构班级:,pnameendl;,delete pname;,2024/9/13,96,void Print();,private:,char * pname;,int num;,;,CClass :CClass (char *cName,int snum),int length = strlen(cName);,pname = new charlength+1;,if (pname!=0) /,或,pname,!,=NULL,strcpy(pname,cName);,num=snum;,cout,创建班级:,pnameendl;,2024/9/13,97,void CClass : Print(),coutpname,班的人数为:,numendl;,void main(),CClass c1(,计算机,061,班,56);,CClass c2 (c1);,c1.Print();,c2.Print();,2024/9/13,98,c1,、,c2,内存分配情况(浅拷贝),2024/9/13,99,问题解决 :,CClass (CClass &p),pname = new charstrlen(p.pname )+1;,if (pname!=0),strcpy(pname,p.pname);,num=p.num ;,cout,创建班级的拷贝:,pname Print(); /,通过指针引用对象成员,输出日期,200-1-1,(*dp2).Print(); /,通过指针指向的对象引用对象成员,输出日期,2006-12-1,delete dp1;/,调用,dp1,的析构函数,delete dp2;/,调用,dp2,的析构函数,2024/9/13,104,1.7.2,对象数组,对象数组中的每一个元素都是类的对象,一、声明一维对象数组的语法形式,类名 数组名,常量表达式,;,注意:在建立数组时,要调用构造函数初始化每个数组元素。,CStudent s3 = CStudent(,张三,2006001,19); CStudent,(,李四,2006002,18); CStudent,(“王五”,2006003,20;,二、引用对象数组元素的公有成员:,数组名,下标, .,成员名;,2024/9/13,105,【,例,1.10,】,设计一个学生类,假设一个班有,5,个学生,计算这个班学生的平均年龄。,#include ,#include ,class CStudent,public:,CStudent(char *na,int i ,int a);,int GetAge();,private:,char name20;,int id;int age;,;,2024/9/13,106,CStudent:CStudent(char *na,int i ,int a),strcpy(name, na);,id=i;,age = a;,int CStudent:GetAge(),return age;,2024/9/13,107,void main(),int sum=0;,CStudent s5 = CStudent(,张三,10001, 20), /,对象数组初始化,CStudent(,李四,10002, 22 ),CStudent(,王五,10003, 24 ),CStudent(,赵六,10004, 26 ),CStudent(,孙六,10005, 28 );,for(int i=0; i5; i+),
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!