C++及Windows可视化程序设计第5章PPT学习教案_第1页
C++及Windows可视化程序设计第5章PPT学习教案_第2页
C++及Windows可视化程序设计第5章PPT学习教案_第3页
C++及Windows可视化程序设计第5章PPT学习教案_第4页
C++及Windows可视化程序设计第5章PPT学习教案_第5页
已阅读5页,还剩172页未读 继续免费阅读

下载本文档

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

文档简介

1、会计学1C+及及Windows可视化程序设计第可视化程序设计第5章章第1页/共177页第2页/共177页的变量属于该类,在某些情况下,变量可以被该类的不同实例所共享。第3页/共177页第4页/共177页;第5页/共177页些成员分别叫做私有成员、公有成员和保护成员。访问权限用于控制对象的某个成员在程序中的可访问性,如果没有使用关键字,则所有成员默认声明为private权限。这些关键字的使用顺序和次数也都是任意的。第6页/共177页第7页/共177页第8页/共177页数声明,还必须在程序中实现这些成员函数。定义成员函数的一般形式为第9页/共177页而“返回类型”则是这个成员函数返回值的类型。余下

2、的工作就是定义成员函数的函数体。例如Setxy是类Point的成员函数,它没有返回值,则定义如下:void Point Setxy(int a,int b) x=a; y=b;第10页/共177页return x;int Point Gety()return y;第11页/共177页数的定义。有些成员函数的实现方式不止一种,例如void Point Display()coutGetx(),Gety()Display;第47页/共177页第48页/共177页数,例如输出x只能使用A.Getx(),不能使用A.x。第49页/共177页配,这种对象建立的过程称为实例化。实例化一词在面向对象程序设计范

3、围内使用广泛,用以表示产生类的实例或物理实体的动作。在某些语言中,对象就被称作实例。虽然在C+中并不是这样,但实例化仍然被广泛使用。第50页/共177页第一条语句称为不完全类声明,它用于在类没有完全定义之前就引用该类的情况,例如引用另一文件中定义的类。由于类标识符MembersOnly通过不完全类声明进入了作用域,所以就可以声明全局变量指针club。编译器执行到该指针的声明处时,只了解指针所指类型是一个叫MembersOnly的类,而不了解其他任何情况。第51页/共177页器先扫描类的成员说明,最后才处理内联成员函数的代码体。第52页/共177页一部分。不过这是早期的做法,对强类型检查的编译器

4、,会给出一个警告。可给空类增加一个无参数构造函数(见构造函数一节)以消除警告。例如:class Empty public: Empty() ;第53页/共177页num的作用域即使该成员函数的实现是在类定义之外给出的,类作用域也包含了类中成员函数的作用域。因此,当成员函数内使用一个标识符时,编译器先在包含类作用域中寻找,例如下面的例子:第54页/共177页类中的一个成员名可以使用类名和作用域运算符来显式指定,这称为成员名限定。例如:void MyClass set(int i)第55页/共177页在程序中使用成员选择运算符(“.”或“-”)访问一个对象的成员时,其后的名字是引用该对象所在类中声

5、明的成员名。例如: Point A;/声明类对象,假设类内有成员函数Getx() int Getx()return 5;/类外面声明的函数第56页/共177页但是,在一个友元函数访问类中的枚举成员时,有时必须使用成员选择运算符。友元函数在后面的章节讨论。除非编译器在处理类声明时遇到了标识其结束的右花括号,否则这个声明仍然是引用性声明。第57页/共177页MyClass d;/正确;第58页/共177页第59页/共177页只出现一个成员。联合使若干数据成员使用同一地址。可以直接在类中使用无名联合,例如:第60页/共177页无名联合中声明的数据项名字可以被直接存取。第61页/共177页目前只是强调

6、联合既不能用做任何类的基类,也不能从任何类中派生出联合,因为联合在特定的时刻只有一个数据成员处于“激活”状态。此外,在联合中也不能说明虚函数。第62页/共177页作。第63页/共177页译器的工作,也降低了效率。但如果采取只能由用户自己来显式调用构造函数方式的话,就又容易破坏安全性。第64页/共177页;第65页/共177页第66页/共177页类名(形参1,形参2,形参n);/可以没有形参类的构造函数可以在类体内(内联函数)声明时定义,也可以在类体外定义。可以使用初始化列表或者在构造函数的函数体内定义。第67页/共177页 xn=形参n; 构造函数的参数是无顺序排列,只要保证相互的对应顺序即可

7、。可以使用默认参数或重载。第68页/共177页;时,程序为对象y分配内存,然后调用带有参数的构造函数来初始化这段内存,将y的数据成员 num 初始化为15,输出“Initializing 15”。第69页/共177页只是引用在其他地方声明的对象,程序并不为外部对象说明调用构造函数。如果是全局对象或静态对象,在main 函数执行之前要调用它们的构造函数。第70页/共177页程序在进入main函数之前先构造全局对象,输出 Initializing 5进入主函数之后输出为: Entering main and exiting main。第71页/共177页第72页/共177页 Initializin

8、g 5第73页/共177页 new Test(5);new 调用了带参数的构造函数,输出Initializing 5使用new建立的动态对象在不用时必须用delete删除,以便释放所占空间。第74页/共177页即它的函数体是空的。因此,当建立 Test 类的一个对象时,对象的状态是不确定的,即没有被初始化。第75页/共177页定义一个无参数的构造函数。需要说明的是“默认”也称为“缺省”,本书统一使用“默认”。解决的另一种方法是将相应的构造函数全部使用默认参数设计。第76页/共177页第77页/共177页个类定义默认参数的构造函数时,则在说明对象数组时必须提供初始值。第8章将进一步介绍对象数组。

9、第78页/共177页X X(X &)第79页/共177页也存在意外。最明显的例子是,如果存在指针时,是简单地将两个指针指向同一地址还是指向不同的存储区域?简单地处理往往导致错误的发生,因为简单的赋值可能使两个指针指向了同一块存储区域(见下图)。第80页/共177页烦。为了克服这样的缺点,需要自定义复制构造函数。第81页/共177页注意: 在这个函数的实现中,它访问了对象的私有成员,这是允许的。C+中,在一个类中定义的成员函数可以访问该类任何对象的私有成员。第82页/共177页Test Test(Test&),使用 obj1 来初始化 obj2。这个构造函数必须使用引用参数。另外,为了安全起见,

10、推荐使用的原型为:Test(const Test&);第83页/共177页第84页/共177页数,但是可以显式地说明参数为void,即形如 X X(void)。从函数重载角度分析,一个类也只能定义一个析构函数且不能指明参数。第85页/共177页void main() Test x(5,68); coutExiting main endl;第86页/共177页的最后一条输出语句之后。当对象的生存期结束时,程序为这个对象调用析构函数,然后回收这个对象占用的内存。全局对象和静态对象的析构函数在程序运行结束之前调用。数组的每个元素调用一次析构函数。全局对象数组和静态对象数组的析构函数在程序结束之前被调

11、用,请读者自行分析。第87页/共177页 deleteptr;第88页/共177页别为这2个对象调用一次构造函数。当使用 delete 释放动态对象数组时,必须告诉这个动态对象数组有几个元素对象,C+使用“ ”来实现。即语句 deleteptr;/注意不要错为ptr 第89页/共177页Test(7,8); for(int i=0; i2; i+) delete ptri;第90页/共177页第91页/共177页;第92页/共177页Test:Test(char *s) /定义构造函数定义构造函数 str=new charstrlen(s)+1; strcpy(str,s); cout Ini

12、tializing strendl;Test:Test() cout Delete strendl; 第93页/共177页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;第94页/共177页第第一个创建的是一个一个创建的是一个Test对象的指针对象的指针ptr1,初始化初始化的值为:的值为: We a

13、re here!析构需要使用一个单独的语句析构需要使用一个单独的语句“delete ptr1;”。第第二个创建的是一个二个创建的是一个Test对象的动态数组,这个数对象的动态数组,这个数组有两个元素,初始化的值在内中顺序排列为:组有两个元素,初始化的值在内中顺序排列为: Here! 0Here!0指针指针ptr2指向首地址,需要使用语句指向首地址,需要使用语句 delete ptr2;来析构这分配给这两个对象的存储空间。来析构这分配给这两个对象的存储空间。第三个创建的是一个第三个创建的是一个Test对象的动态数组,这个数对象的动态数组,这个数组有两个元素,初始化的值分别为:组有两个元素,初始化

14、的值分别为: 对象对象第95页/共177页 ptr30内容为内容为 We;ptr31内容为内容为 You。所以要使用循环语句逐个析构。所以要使用循环语句逐个析构。输输出结果如下:出结果如下: Initializing We are here! Initializing Here! Initializing Here! Initializing We Initializing You Delete We are here! Delete Here! Delete Here! Delete We Delete You第96页/共177页第97页/共177页第98页/共177页第99页/共177页第

15、100页/共177页第101页/共177页数Copy Initializing /需要调用复制构造函数第102页/共177页call C=fun() /C使用函数fun()的返回值Initializing /在函数fun()内创建对象ACopy Initializing /调用复制构造函数返回值delete.101,202 /返回值给对象C,调用析构 /函数清除临时对象A第103页/共177页,清除对象Bdelete.42,35 /调用析构函数清除对象A下面重点解释调用复制构造函数的3种情况: 当用一个类的对象去初始化另一个对象时,调用复制构造函数: Point A(14,25);/调用构造函

16、数初始化对象A第104页/共177页 display(B);因为传对象是传值方式,所以需要产生一个副本,这就是临时对象。调用复制构造函数产生副本,在退出函数时,调用析构函数析构临时对象,输出信息为:第105页/共177页用作为参数,所以不需要临时对象。执行语句“disp(B);”的输出结果为: X=42,Y=35 /进入函数体执行语句,不需要 /调用复制构造函数第106页/共177页 /临时对象 delete.101,202 /将值传给对象C,调用 /析构函数清除临时对象 delete.101,202 /退出函数体,调用析构 /函数清除对象A第107页/共177页生一个临时对象,用这个临时对象

17、完成C=A,然后再析构这个临时对象,这就是中间两条输出信息。这样,语句“C=func();”就输出如上4条信息。第108页/共177页利用它们完成一些函数功能。第109页/共177页 str s1(hello),s2(world); s2=s1;第110页/共177页图图5.1 s2=s1,使它们具有相同的内存块,使它们具有相同的内存块第111页/共177页图图5.2 定义定义“=”,使,使 s2=s1具有各自具有各自(内容相同)的内存块(内容相同)的内存块第112页/共177页;st=new charstrlen(a.st)+1;/申请内存strcpy(st,a.st);/将对象a的数据复制

18、一份 /到申请的内存区return*this; /返回this指针指向的对象第113页/共177页str& str operator=(str&);”,即函数operator=(str&)返回str类对象的引用。定义时记作:str& str operator=(str&a) /函数体第114页/共177页C+编译器将其解释为 s3.operator=(s2.operator=(s1);下面给出str类的完整实现和测试主程序,以便读者对比分析。第115页/共177页第116页/共177页第117页/共177页第118页/共177页WeWeWeGo home!第119页/共177页类名n成员名n;

19、 ;第120页/共177页成员初始化列表,其中的参数表给出为调用相应成员所在类的构造函数时应提供的参数。这些参数一般来自“参数表0”,可以使用任意复杂的表达式,其中可以有函数调用。如果某项的参数表为空,则表中相应的项可以省略。第121页/共177页第122页/共177页第123页/共177页第124页/共177页第125页/共177页的默认构造函数Constructor for object 6 /为对象成员one调用 /构造函数Constructor for object 5 /为对象成员two调用 /构造函数Constructor for container 10 /为对象anObj调用

20、/container类的有参构造函数第126页/共177页构对象objDestructor for object 0 /析构对象twoDestructor for object 0 /析构对象one在这个程序中, container类包含有两个object类的对象成员one和two。第127页/共177页第128页/共177页第129页/共177页其是类的描述,常称之为类模板。第130页/共177页第131页/共177页差异。为了创建类模板,在模板参数表之后,应有类声明。在类中可以像使用其他类型(如int或double)那样使用模板参数。例如,可以把模板参数用做数据成员,返回类型的成员函数或成

21、员函数的参数。下面是一个具体实例:第132页/共177页;函数;类模板TAnyTemp声明了两个私有数据成员,即类型都为T的数据成员x和y,一旦使用类模板,它就可以保存被指定类型的两个值。第133页/共177页告诉编译器从模板产生一个类,并用int替换所有的参数T,所产生的类的名字变成TAnyTemp定义的对象名为iObject。两个整型值321和556传递给对象的构造函数以初始化该对象的私有数据对象。第134页/共177页只要赋给模板一种实际的数据类型,就会产生新的类,而且以特定类型替代模板参数。下面还是以求4个数的最大值为例。第135页/共177页第136页/共177页第137页/共177

22、页第138页/共177页第139页/共177页是用以操作这些容器类的所谓泛型算法(generic algorithm),包括find(),sort(),replace()和merge()等。第140页/共177页器身上进行操作。这是借助一对iterators(迭代子)实现,它是一种泛型指针。第141页/共177页中的rbegin和rend是提供给逆向泛型指针的开始和结束标志。逆向泛型指针的加操作是使它向rend方向移动,减操作向rbegin移动。它的定义方法如下:vectorreverse_iterator 指针名; /reverse_iterator是逆向泛型指针关键字第142页/共177页

23、第143页/共177页第144页/共177页第145页/共177页由于篇幅关系,仅作简单介绍。STL现在有75个泛型算法,下面给出最常用的算法。第146页/共177页 copy() remove() remove_if() replace() replace_if() swap() unique() 关系算法:equal() includes() mismatch()第147页/共177页下共同操作: equality(=)和inequality(!=)运算符,返回true或false。 assignment(=)运算符,将某个容器复制给另一个容器。第148页/共177页第149页/共177页第150页/共177页。为了验证这一点,没有使用b.end()而改用P的位置,结果没有复制P。第151页/共177页泛型算法是C+标准程序库的骨干部分,都经过精心设计和严格测试,可以放心使用。第152页/共177页在.cpp文件中,将头文件包含进去。主程序可单独使用一个文件,这就是多文件编程规范。第153页/共177页第154页/共177页

温馨提示

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

评论

0/150

提交评论