C++及Windows可视化程序设计PPT精选文档_第1页
C++及Windows可视化程序设计PPT精选文档_第2页
C++及Windows可视化程序设计PPT精选文档_第3页
C++及Windows可视化程序设计PPT精选文档_第4页
C++及Windows可视化程序设计PPT精选文档_第5页
已阅读5页,还剩172页未读 继续免费阅读

下载本文档

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

文档简介

1、第5章 对象和类,5.1 类及其实例化 5.2 类和对象的性质 5.3 结构和联合 5.4 构造函数 5.5 析构函数 5.6 综合例题,5.7 重载对象的赋值运算符 5.8 对象成员的初始化 5.9 类模板与标准模板库 5.10 面向对象编程的文件规范 实验 习题,本章重点介绍在C+中定义类、建立和使用对象的方法。虽然同类对象在其数据成员的取值方面是不相同的,但可以共用相同的代码。 类是对同类对象的描述,它不但描述了对象之间的公有接口,同时也给出了对象的内部实现(数据成员和成员函数,像构造枚举和结构一样,类也是一种用户自己构造的数据类型并遵循C+的规定。 例如,类也要先声明后使用;不管声明的

2、内容是否相同,声明同一个名字的两个类是错误的,类是具有惟一标识符的实体;在类中声明的任何成员不能使用extern、auto和register关键字进行修饰;类中声明的变量属于该类,在某些情况下,变量可以被该类的不同实例所共享,5.1 类及其实例化 5.1.1 定义类,类和其他数据类型不同的是,组成这种类型的不仅可以有数据,而且可以有对数据进行操作的函数,它们分别叫做类的数据成员和类的成员函数,而且不能在类声明中对数据成员使用表达式进行初始化,1. 声明类 类是对一组性质相同对象的程序描述。在C+中声明类的一般形式为 class 类名 private: 私有数据和函数 public: 公有数据和

3、函数 protected: 保护数据和函数,类声明以关键字class开始,其后跟类名。 类所声明的内容用花括号括起来,右花括号后的分号作为类声明语句的结束标志。这一对花括号“”之间的内容称为类体。 类中定义的数据和函数称为这个类的成员(数据成员和成员函数)。 类成员均具有一个属性,叫做访问权限,通过它前面的关键字来定义。顾名思义,关键字private 、public和protected 以后的成员的访问权限分别是私有、公有和保护的,把这些成员分别叫做私有成员、公有成员和保护成员。 访问权限用于控制对象的某个成员在程序中的可访问性,如果没有使用关键字,则所有成员默认声明为private权限。这些

4、关键字的使用顺序和次数也都是任意的,例5.1】 描述点的Point类。 class Point /类名Point private: /声明为私有访问权限 int x,y;/私有数据成员 public: /声明为公有访问权限 void Setxy(int a,int b);/无返回值的公有成员函数 void Move(int a,int b);/无返回值的公有成员函数 void Display();/无返回值的公有成员函数 int Getx(); /返回值为int的公有成员函数 int Gety(); /返回值为int的公有成员函数 ; /类声明以分号结束 x和y是私有成员,Setxy、Disp

5、lay、Move、Getx和Gety是公有成员。因为只是声明函数,所以可只给出函数原型。【例5.2】是其等效的声明方式,例5.2】 使用默认关键字及改变关键字顺序和次数的Point类。 class Point /类名Point int x;/默认私有数据成员 public: /声明为公有访问权限 /无返回值的公有成员函数Setxy的函数原型 void Setxy(int,int); /无返回值的公有成员函数Move的函数原型 void Move(int,int); void Display();/无返回值的公有成员函数的函数原型 int Getx(); /返回值为int的公有成员函数的函数原型

6、 int Gety(); /返回值为int的公有成员函数的函数原型,private: /声明为私有访问权限 int y;/私有数据成员 ; /类定义以分号结束 由此可见,成员函数声明的规则与第4章所述的函数声明规则相同。 2. 定义成员函数 类中说明的成员函数用来对数据成员进行操作。例如,Point类的Setxy函数用来为该类的对象设置初始值,而当调用成员函数Getx时,则返回一个对象的数据成员x的值。 在类中只对这些成员函数进行了函数声明,还必须在程序中实现这些成员函数。 定义成员函数的一般形式为,返回类型 类名成员函数名(参数列表) 成员函数的函数体/内部实现 其中“”是作用域运算符,“类

7、名”是成员函数所属类的名字,“”用于表明其后的成员函数是属于这个特定的类。换言之,“类名成员函数名”的意思就是对属于“类名”的成员函数进行定义,而“返回类型”则是这个成员函数返回值的类型。余下的工作就是定义成员函数的函数体。 例如Setxy是类Point的成员函数,它没有返回值,则定义如下: void Point Setxy(int a,int b) x=a; y=b,将“void PointSetxy(int a,int b)”理解为定义Point的函数成员Setxy(int a,int b),该成员带有两个整型参数,函数没有返回值(void)。按此方法,可写出其他几个成员函数的定义: vo

8、id Point Move(int a,int b) x=x+a; y=y+b; void Point Display() coutx,yendl; int Point Getx() return x; int Point Gety() return y,也可以使用关键字inline将成员函数定义为内联函数,例如: inline int Point Getx() return x; 如果在声明类的同时,在类体内给出成员函数的定义,则默认为内联函数。例如在类中将声明Getx的语句“int Getx();”改为“int Getx()return x;”,则Getx为内联函数。 一般直接在类体内给出

9、简单成员函数的定义。有些成员函数的实现方式不止一种,例如 void Point Display() coutGetx(),Gety()endl,是调用成员函数Getx()和Gety()实现的,它们使用了cout流,应在定义之前包含如下语句: #include using namespace std; 3. 数据成员的赋值 不能在类体内给数据成员赋值,即下面的方法是错误的: Class Point int x=25,y=56;,当然,在类体外面就更不允许了。 数据成员的具体值是用来描述对象的属性的。只有产生了一个具体的对象,这些数据值才有意义,所以又称对象的初值或对象初始化。 这跟简单数据类型的

10、道理一样,int是整数类型,但需要声明整数对象之后才有意义,“int x=5;”使得整数对象x的值为5,只是类具有成员函数而已。 假设已经有了一个对象A,则可使用“.”运算符调用成员函数Setxy赋初值。例如: A.Setxy(25,56,将对象A的数据成员x和y分别赋给25和56,即A.x=25,A.y=56。其实,真正的初始化是使用与Point同名的构造函数Point(int,int)实现的。 在1.10.1节介绍使用string的对象str时,使用“string str(real is);”语句。按此推理,可以写出产生Point的对象的语句: Point A(25,56); 这就是使用构

11、造函数产生类的实例。不过,现在还没有定义构造函数Point(int,int),所以还不能使用这种方法。但可以看到数据封装的迹象了,Point类是用户定义的一种类型,Point类所说明的数据成员描述了对象的内部数据结构,对数据成员的访问通过类的成员函数来进行。 使用Point在程序中声明变量,具有Point类的类型的变量被称为Point的对象。只有产生类的对象,才能使用这些数据和成员函数。 类Point不仅可以声明对象,还可以声明对象的引用和对象的指针,语法与基本数据类型一样。 Point A,B; /定义Point类型的对象A和B Point *p= for(int i=0; i2; i+)

12、delete ptri;,必须为每个数组元素调用delete析构相应的对象数组元素所占的空间。输出结果如下: Initializing 2,4 Initializing 7,8 Destructor is active Destructor is active 数据成员使用指针时,需要为它们申请空间,要注意区分动态对象数组和指针数组的区别,以及析构时的异同。注意分析下面的例子,include using namespace std; class Test private: char *str; public: Test(char *str=Here!); Test();,Test:Test(c

13、har *s) /定义构造函数 str=new charstrlen(s)+1; strcpy(str,s); cout Initializing strendl; Test:Test() cout Delete strendl;,void main ( ) Test *ptr1=new Test(We are here!); Test *ptr2=new Test2; Test *ptr32=new Test(We), new Test(You) ; delete ptr1; delete ptr2; for(int i=0; i2; i+) delete ptr3i;,第一个创建的是一个T

14、est对象的指针ptr1,初始化的值为: We are here! 析构需要使用一个单独的语句“delete ptr1;”。 第二个创建的是一个Test对象的动态数组,这个数组有两个元素,初始化的值在内中顺序排列为: Here! 0Here!0 指针ptr2指向首地址,需要使用语句 delete ptr2; 来析构这分配给这两个对象的存储空间。 第三个创建的是一个Test对象的动态数组,这个数组有两个元素,初始化的值分别为: 对象,ptr30内容为 We;ptr31内容为 You。 所以要使用循环语句逐个析构。 输出结果如下: Initializing We are here! Initial

15、izing Here! Initializing Here! Initializing We Initializing You Delete We are here! Delete Here! Delete Here! Delete We Delete You,如果在定义类时没有定义析构函数,C+编译器要为这个类产生一个默认的析构函数。正如没有给类定义构造函数,C+编译系统会产生一个默认构造函数一样,编译器也为它产生一个函数体为空的默认析构函数: TestTest(,5.5.3 默认析构函数,例5.9】 演示调用构造函数及 析构函数的综合例题。 下面这个程序综合演示了调用构造函数、调用复制构造

16、函数及调用析构函数的顺序,并演示了调用复制构造函数的3种不同情况。 另外,本程序还比较了函数使用对象和对象的引用为参数的情况,5.6 综合例题,include using namespace std; class Point private: int X,Y; public: Point(int a=0,int b=0) /构造函数 X=a; Y=b; coutInitializingendl; Point(const Point 以绕过类型转换所带来的运行时间开销。 程序运行结果如下: We They We We We Go home,可以在一个类中说明具有某个类的类型数据成员,这些成员称为

17、对象成员。 在类X中说明对象成员的一般形式为: class X 类名1成员名1; 类名2成员名2; 类名n成员名n;,5.8 对象成员的初始化,说明对象成员是在类名之后给出对象成员的名字。为初始化对象成员,X类的构造函数要调用这些对象成员所在类的构造函数,X类的构造函数的定义形式如下: X X(参数表0): 成员1(参数表1), 成员2(参数表2),成员n(参数表n) /其他操作 冒号“:”后由逗号隔开的项组成成员初始化列表,其中的参数表给出为调用相应成员所在类的构造函数时应提供的参数。这些参数一般来自“参数表0”,可以使用任意复杂的表达式,其中可以有函数调用。如果某项的参数表为空,则表中相应

18、的项可以省略,对象成员构造函数的调用顺序取决于这些对象成员在类中说明的顺序,与它们在成员初始化列表中给出的顺序无关。 当建立X类的对象时,先调用对象成员的构造函数,初始化对象成员,然后才执行X类的构造函数,初始化X类中的其他成员。 析构函数的调用顺序与构造函数正好相反。 下面分析一个实际的例子,例5.11】 分析下面程序中析构函数与构造函数的调用顺序。 #include using namespace std; class object private: int val; public: object(): val(0) coutDefault constructor for object“e

19、ndl; object(int i): val(i) coutConstructor for object“valendl; object() coutDestructor for object“valendl;,class container private: object one;/初始化顺序与对象成员产生的顺序有关 object two;/排在前面的先初始化 int data; public: container(): data(0) coutDefault constructor for container“endl; container(int i,int j,int k); con

20、tainer() coutDestructor for container“dataendl;,与初始化列表顺序无关 container container(int i,int j,int k): two(i),one(j) data=k; coutConstructor for container“dataendl; void main() container obj,anObj(5,6,10); 程序运行结果如下,Default constructor for object /为对象成员one调用 /默认构造函数 Default constructor for object /为对象成员t

21、wo调用 /默认构造函数 Default constructor for container/为对象obj调用 /container类的默认构造函数 Constructor for object 6 /为对象成员one调用 /构造函数 Constructor for object 5 /为对象成员two调用 /构造函数 Constructor for container 10 /为对象anObj调用 /container类的有参构造函数,Destructor for container 10 /调用container类的析 /构函数析构对象anObj Destructor for object

22、 5 /析构数据成员为5的对象two Destructor for object 6 /析构数据成员为6的对象one Destructor for container 0 /调用container类的析构 /函数析构对象obj Destructor for object 0 /析构对象two Destructor for object 0 /析构对象one 在这个程序中, container类包含有两个object类的对象成员one和two,对基本数据类型的成员的初始化也可以在成员初始化列表中进行,例如: container container(int i,int j,int k) : two

23、(i),one(j),data(k) 当初始化const成员和引用成员时,必须通过成员初始化列表进行。 例如下面的例子,class example private: const int num; int Point有输出两点距离的函数Distance。 给出Line类的实现并设计满足要求的类模板Point。 分析输出结果,总结构造函数和析构函数的调用顺序,3. 提示 Line的对象不能直接存取Point对象的私有数据成员。 要求Display(Line&)函数也输出两个端点坐标之间的距离,参数是Line对象的引用。假设为“Line&s”,则引用点对象a的形式是s.a。对于a的成员函数,s.a要

24、用“.”运算符去调用,例如,使用“s.a.Display();”显示Line对象的一个端点坐标。 可以先不使用类模板,试验成功之后再改为模板。 注意类模板函数成员在声明之外定义和作为内联函数定义方法的异同,5-1 设计一个点类Point,再设计一个矩形类,矩形类使用Point类的两个坐标点作为矩形的对角顶点,并可以输出4个坐标值和面积。使用测试程序验证程序。 5-2 使用内联函数设计一个类,用来表示直角坐标系中的任意一条直线并输出它的属性。 5-3 定义一个类模板,计算24个数据的最小值并用不同数据测试类的正确性,习题,5-4 下面是以传统形式的struct来定义一个存放字符的栈类型,并定义了有关栈操作的各种函数。编写一个主函数,定义并输入一个字符串,用此串来验证栈的各种操作,包括把串压入栈中后再弹出,以相反的次序将它们显示出来。 const max_len=1000; enum boolean false,true; enum EMPTY=-1,FULL=max_len-

温馨提示

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

评论

0/150

提交评论