C++面向对象程序设计(谭浩强版).ppt_第1页
C++面向对象程序设计(谭浩强版).ppt_第2页
C++面向对象程序设计(谭浩强版).ppt_第3页
C++面向对象程序设计(谭浩强版).ppt_第4页
C++面向对象程序设计(谭浩强版).ppt_第5页
已阅读5页,还剩795页未读 继续免费阅读

下载本文档

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

文档简介

1、C+面向对象程序设计,第一讲,第一章 C+的初步知识 第二章 类和对象 第三章 关于类和对象的进一步讨论 第四章 运算符重载 第五章 继承与派生 第六章 多态性与虚函数 第七章 输入输出流,结束放映,第一章 C+的初步知识,1.1 从C到C+ 1.2 C+语言的词法和词法规则 1.3 最简单的C+程序 1.4 C+对C的扩充 1.5 C+程序的编写和实现,1.1 从C到C+,C语言是结构化和模块化的语言,C程序的设计者必须细致地设计程序中的每个细节,准确地考虑程序运行时每一时刻发生的事情,当程序规模变大时,结构化程序设计就显得力不从心。 为了解决软件设计危机,在20世纪80年代提出了面向对象的

2、程序设计思想(OOP)在实践中人们发现C语言使用如此广泛,如果在它的基础上发展一种面向对象的语言,一定会让大众容易接收这种语言,所以产生了C+。,AT / 使用命名空间std int main() coutThis is a C+ program.n; / 上面用C+的方法输出一行 return 0; ,(1)标准C+规定main函数必须声明为int类型,如果程序正常运行,向操作系统返回一个零值,否则返回非零值,通常是-1。 (2)C+程序中可以用/*/做注释,可以用/做注释。前者可以做多行注释,后者只做单行注释。 (3)C+程序中常用cout、cin进行输出输入,cout是C+定义的输出流对

3、象,是插入运算符。,(4)使用cout、cin需要用头文件iostream,在程序开始要用#include声明包含的头文件。 (5) using namespace std; 意思是使用命名空间。C+标准库中的类和函数是在命名空间std中声明的,因此程序中如用C+标准库中的有关内容(此时需要用#include命令行),就要用using namespace std; 语句声明。,例1.2 求a和b 两个数之和 / 求两数之和 #include / 预处理命令 using namespace std; / 使用命名空间std int main() / 主函数首部 / 函数体开始 int a,b,s

4、um; / 定义变量 cinab; / 输入语句 sum=a+b; / 赋值语句 couta+b=sumendl; / 输出语句 return 0; / 如程序正常结束,返回一个零值 ,cin 是C+定义的输入流对象。”是提取运算符,与cin配合,其作用是从输入设备中提取数据送到输入流cin中。在程序执行时,键盘输入的第一个数据赋予a,第二个数据赋予b 。 cout语句中的endl是C+控制符常数,作用是让光标换行。 如果在本程序运行时输入: 123 456 程序则输出: a+b = 579,例1.3 求两个数中的大数 #include using namespace std; int mai

5、n() int max(int x,int y) ; /对max函数作声明 int a,b,c; cinab; c=max(a,b); /调用max函数 coutmax=cendl; return 0; ,int max(int x,int y) /定义max函数 int z; if(xy) z=x; else z=y; return(z); ,本程序包含两个函数,主函数main和被调用的函数max。max函数的作用是将两个整数中的大数赋予变量z。return语句将z的值返回给主函数main。返回值是通过函数名max带回到main函数的调用处。 程序运行情况如下: 18 25 (输入18和25

6、) max = 25 (输出最大值25),第二讲,例1.4包含类的C+程序 #include using namespace std; class Student / 声明一个类,类名为Student private: / 以下为类中的私有部分 int num; / 私有变量num int score; / 私有变量score public: / 以下为类中公用部分 void setdata() / 定义公用函数setdata cinnum; / 输入num的值 cinscore; / 输入score的值 void display() / 定义公用函数display coutnum=numen

7、dl; / 输出num的值 coutscore=scoreendl; ; / 输出score的值 ; / 类的声明结束,Student stud1,stud2; /定义stud1和stud2为Student类的变量,称为对象 int main() / 主函数首部 stud1.setdata(); / 调用对象stud1的setdata函数 stud2.setdata(); / 调用对象stud2的setdata函数 stud1.display(); / 调用对象stud1的display函数 stud2.display(); / 调用对象stud1的display函数 return 0; ,程

8、序中声明一个被称为类的类型Student。声明时要用关键字class。C+类中可以包含两种成员即数据(如变量num、 score)和函数(如setdata函数和 display函数)。分别称为数据成员和成员函数。 在C+ 中将一组数据和访问这组数据的函数封装在一起,组成类。一个类是由一组数据,一组对其访问的若干函数,以及数据和函数的访问属性组成的。在前面程序中看到的private (私有) public(公有)保留字代表数据和函数的访问属性。,凡是指定为公有的数据和函数,既可由本类的函数访问和调用,也可由其他函数或语句访问和调用;凡是指定为私有的数据和函数,通常只能由本类的函数访问和调用。 程

9、序中“Student stud1,stud2; ”是一个定义语句,定义两个Student 类型变量stud1和stud2, Student 类与int一样是C+的合法类型。,具有类类型的变量称为对象。 Student的对象stud1,stud2具有同样的结构和特征。 在类外调用成员函数时必须在函数名前冠以类的名称。,主函数中第一条语句输入学生1的学号和成绩,第二条语句输入学生2的学号和成绩,第三条语句输出学生1的学号和成绩,第四条语句输出学生2的学号和成绩。程序运行情况如下: 1001 98.5 1002 76.5 num=1001 Score=98.5 num=1002 Score=76.5

10、,为了与C兼容, C+保留了C语言中的一些规定,例如头文件的文件名,以C语言里头文件的扩展名是 .h,许多C+编译系统保留了这种扩展名,近年推出的C+编译系统新版本,推出了一批不带扩展名的头文件如iostream,string ,cmath 等。为了兼容C+仍允许使用带扩展名的头文件。由于C语言无命名空间,因此使用带扩展名的头文件时不用using namespace std。,1.3 C+对C的扩充,C+既可用于面向过程的程序设计,也可用于面向对象程序设计。C+继承了C语言提供的绝大部分功能和语法规定,并在此基础上作了扩充。,1.4.1 C+的输入和输出 1.4.2 用const 定义常变量

11、1.4.3 函数原型声明 1.4.4 函数的重载 1.4.5 函数模板 1.4.6 有默认参数的函数,1.4.7 变量的引用 1.4.8 内置函数 1.4.9 作用域运算符 1.4.10 字符串变量 1.4.11 动态分配/回收内存运算符,1.3.1 C+的输入输出,C+为了方便使用,除了可以利用printf和scanf函数进行输入和输出外,还增加了标准输入流输出流cin和cout。它们是在头文件iostream中定义的,标准流是不需要打开文件和关闭文件就能直接操作的流式文件,在此标准输入流是指从键盘上输入的数据,标准输出流是指向屏幕输出的数据流。C+预定义的标准流如表1.2所示。,1. 用c

12、out进行输出,格式: cout 表达式1表达式2 功能:由左向右逐个计算表达式的值,将其插入到输出流cout中。 cout 必须与输出运算符一起使用,每个后跟一个表达式,运算符的结合方向是从左向右,所以各个表达式的值按从左到右的顺序插入到输出流中。,For ( k = 1; k =3; k+) cout “k=“ kendl endl是C+输出流的常数,在头文件iostream中定义,代表让光标换行。在C+中也可以用”n”控制光标换行。所以输出语句也可写成: cout “k=“ k“n”,2. 用cin进行输入,格式: cin变量1 变量2 是C+的提取运算符,表示从标准输入设备取得数据,赋

13、予其后的变量。 从键盘输入数值数据时,两个数据之间用空格分隔或用回车分隔。,int a; float b cinab; 从键盘输入 20 32.45 ,例1.5 cin和cout的使用,#include using namespace std; int main( ) coutname; cinage; coutyour name is nameendl; coutyour age is ageendl; return 0; ,1.3.2用const定义常变量,格式: const 类型 变量名 = 常数 例:const float PI= 3.14159;,1.3.3函数原型声明,C+规定,如

14、果函数调用在函数定义之前,要求在调用之前声明该函数的原型。 格式:函数类型 函数名(形参表); 形参表中形参可以只写类型。 例: int max ( int x , int y ); 或 int max( int , int ); 其实C+编译时,只检查参数的数据类型。,1.3.4函数的重载,C+允许在同一个域中用一个函数名定义多个函数,这些函数的参数个数、参数类型不相同。用一个函数名实现不同的功能,就是函数的重载。 例1.6 设计程序计算三个数中的大数,#include using namespace std; int max(int a,int b,int c) /求3个整数中的最大者 i

15、f (ba) a=b; if (ca) a=c; return a; float max(float a,float b, float c) /求3个实数中的最大者 if (ba) a=b; if (ca) a=c; return a; long max(long a,long b,long c) /求3个长整数中的最大者 if (ba) a=b; if (ca) a=c; return a; ,int main( ) int a,b,c; float d,e,f; long g,h,i; cinabc; cindef; cinghi; int m; m= max(a,b,c); /函数值为整

16、型 cout max_i=mendl; float n; n=max(d,e,f); /函数值为实型 coutmax_f=nendl; long int p; p=max(g,h,i); /函数值为长整型 coutmax_l=pendl; return 0; ,例 1.7,下面的例子说明用函数重载设计参数个数不同的函数,用一个函数名求两个整数或三个整数中的最大数。 #include using namespace std; int max(int a,int b,int c) /求3个整数中的最大者 if (ba) a=b; if (ca) a=c; return a; ,int max(in

17、t a, int b) /求两个整数中的最大者 if (ab) return a; else return b; int main( ) int a=7,b=-4,c=9; coutmax(a,b,c)endl; /输出3个整数中的最大者 coutmax(a,b)endl; /输出两个整数中的最大者 return 0; ,注意:不允许函数参数个数、参数类型都相同,只是函数返回值不同。因为系统无法从调用形式上判断调用与哪个函数相匹配。,1.3.5函数模板,如果两个函数的参数个数相同,函数的行为相同(做同样的事),只是函数和参数的数据类型不同,如果用函数重载的话,编写的函数代码是相同的,为了节省时

18、间,C+提供了函数模板功能。 格式: template typename 标识符, typename 标识符, 函数定义(函数的类型和参数的类型用声明的标识符表示),template 是关键字,含义是模板 typename 是关键字,表示其后的标识符代表类型参数,调用时根据实参的类型确定形参的类型。 所谓函数模板,是建立一个通用函数,不指定函数类型和参数类型,而用一个虚拟的类型表示。在调用函数时,用实参的类型取代模板中的虚拟类型。 例1.8 为计算两个数中的大数定义函数模板,#include using namespace std; template T max(T a,T b,T c) /用

19、虚拟类型T表示类型 if(ba) a=b; if(ca) a=c; return a; ,int main() int i1=8,i2=5,i3=6,i; double d1=56.9,d2=90.765,d3=43.1,d; long g1=67843,g2=-456,g3=78123,g; i=max(i1,i2,i3); d=max(d1,d2,d3); g=max(g1,g2,g3); couti_max=iendl; coutd_max=dendl; coutg_max=gendl; return 0; ,从程序中看到,此问题用函数模板比用函数重载更方便。注意,函数模板只适用于函数参

20、数的个数相同而类型不同,并且函数体相同的情况,如果函数的参数个数不同,则不能用函数模板。,1.4.6有默认参数的函数,C+允许为函数的参数设置默认值,这时调用函数时,如果没有实参,就以默认值作为实参值。 格式: 形参类型 形参变量名 = 常数 功能:调用函数时,如果没有实参,就以常数作为该形参的值;如果有实参,仍以实参的值作为该形参的值。 注意:有默认值的形参必须放在形参表的右边,不允许无默认参数值和有默认参数值的形参交错排列。,例:编写计算圆柱体体积函数 float volume ( float h, float r = 12.5) 调用可以采用以下任何一种形式: volume( 45.6)

21、; volume( 32.5, 10.5); 函数参数结合从左到右,用第一种方式调用时,只有一个实参,圆半径的值取默认值12.5,用第二种方式调用时,有两个实参,圆半径的值取实参的值10.5。,注意: 一、如果用函数原型声明,只要在函数原型声明中定义形参的默认值即可。 二、一个函数名不能同时用于重载函数和带默认形参值的函数。当调用函数时,如少写一个参数,系统无法判断是利用重载函数还是利用带默认参数值的函数,出现二义性。,例如将例1.7中的第三行改为 int max (int a, int b, int c = 100); 此时 max是重载函数,又带默认参数值,如果出现max( 5, 23)形

22、式的调用,编译系统无法断定调用哪个函数,于是发出编译出错的信息。,1.4.7变量的引用,C+提供了为变量取别名的功能,这就是变量的引用。 格式: 类型 int 变量a 有两个别名b和c。,#include using namespace std; int main( ) int a=10; int ,图1.1,程序运行结果如下: 100 20 20,将引用作为函数参数,C+除了可以用普通变量、指针变量做形参外,还可以用引用变量做形参。 (1)用普通变量做形参 这时传递的是实参的值,在函数内形参与实参是两个不同的内存单元,对形参的修改不会影响实参的值。 例1.10无法实现两个变量的值互换的程序,

23、#include using namespace std; void swap(int a,int b) int temp; temp=a; a=b; b=temp; / 实现a和b的值互换 ,int main( ) int i=3,j=5; swap(i,j); couti,jendl; / i和j的值未互换 return 0; ,图1.2,(2)用指针变量做形参 C语言还允许用指针变量做形参,这时传递的是实参变量的地址(指针),在函数内利用这个指针访问实参变量。 例1.11用指针变量做形参,实现两个变量值的交换。,#include using namespace std; void swa

24、p(int *p1,int *p2) int temp; temp=*p1; *p1= *p2; *p2=temp; ,int main( ) int i=3,j=5; swap( ,图1.3,(3)用引用变量做形参 用指针变量做形参,它将实参变量的地址传递给形参,在函数内用“*指针变量”的方式访问实参变量。我们知道引用变量是变量的别名,在调用函数时,用引用变量做的形参就成了实参变量的别名,在函数中用的形参名就是实参的别名,这样比用指针变量更直观、更方便。,例1.12利用引用变量实现两个变量值的交换 #include using namespace std; void swap(int ,in

25、t main( ) int i=3,j=5; swap(i,j); couti=i j=jendl; return 0; ,图1.4,对引用的进一步说明,(1)引用变量都具有非void类型 (2)不能建立引用的数组 (3)可以建立常引用变量,不允许修改常引用变量的值 例: int i ; const int / i 不是常变量,可以修改,(4)可以建立指针变量的引用变量 例:int i; int *p = / pt是p的别名变量,同时 / 也是指针变量,1.4.8内置函数,C+ 提供了一种机制,在编译时,将所调用的函数的代码嵌入到调用函数代码中,在执行函数时省去了调用环节,提高了函数的执行速度

26、。这种机制称为内置函数,有的书称内联函数。 格式: inline 函数类型 函数名(形参表) 函数体 inline 是C+的关键字,在编译时,编译程序会把这个函数嵌入到调用函数的函数体中 调用格式: 函数名(实参表),例1.13计算三个整数中的大数 #include using namespace std; inline int max(int a,int b,int c) / 这是一个内置函数, / 求3个整数中的最大者 if (ba) a=b; if (ca) a=c; return a; int main( ) int i=7,j=10,k=25,m; m=max(i,j,k); cou

27、tmax=mendl; return 0; ,由于在定义函数时指定它是内置函数,因此编译系统在遇到函数调用max( i,j,k ) 时就用max函数体的代码代替max( i,j,k ) ,同时用实参代替形参。调用语句m= max( i,j,k ) 就被置换成: a=i ; b = j ; c= k; if ( ba) a=b; if ( ca) a=c; m=a; ,例1.15用内置函数计算平方根 #include using namespace std; inline int power(int x) /定义内置函数 return x*x; int main() coutpower(2)en

28、dl; coutpower(1+1)endl; return 0; ,编译程序遇见内置函数power时,先求出函数的实参值(1+1=2),然后用power函数体代替函数调用,调用语句变成: cout2*2endl; cout2*2endl; 运行结果是 4 4,使用内置函数可以节省程序的运行时间,但增加了目标程序的长度。所以在使用时要衡量时间和空间的得失。,1.4.9作用域运算符,并不是所有的变量在程序运行的时时刻刻都是可见的。有的变量在整个程序运行期间都是可见的,称它们为全局变量;有的变量只能在一个函数中可知,被称为局部变量。 每个变量都有其有效的作用域,程序只能在变量的有效的作用域内使用变

29、量,不能直接使用其他域中的变量。,程序的内存区域,程序的内存空间,代码区,全局数据区,堆区,栈区,程序中各个函数的代码,程序中全局数据和静态数据,程序中的动态数据,程序中各函数内的数据,例1.16局部变量和全局变量同名 #include using namespace std; float a=13.5; int main( ) int a=5; coutaendl; return 0; ,程序中有两个变量a,一个是全局变量,另一个是main函数的局部变量,根据局部变量会屏蔽同名的全局变量规则,在函数中出现的变量a是局部变量,因此输出的值是5,而不是13.5,为了在函数中访问全局变量C+提供了

30、作用域运算符 : ,可以用来指定要访问的作用域,可以把main函数改写成,#include using namespace std; float a=13.5; int main( ) int a=5; coutaendl; cout:aendl; return 0; :a表示全局变量a。注意不能用:访问局部变量。,1.4.10字符串变量,C+提供了字符串类类型string,实际上它不是C+的基本类型,它是在C+标准库中声明的一个字符串类,程序可以用它定义对象。 1.定义字符串变量 格式: string 变量名表; 可以在定义变量时用字符串常量为变量赋初值: string 变量名 = 字符串常

31、量 注意:如用字符串变量,在程序开始要用包含语句把C+标准库的string头文件包含进来。,2.对字符串操作 对字符串变量赋值 字符串变量= 字符串表达式 例: string st1,st2; st1 = “王点点“; st2 = st1;, 访问字符串中的字符 C+允许把字符串作为字符数组,第一个字符的下标是0,第二个字符的下标是1,以此类推。 例:string w = “ then”; w2 = a; 结果字符串w变成 than,输入输出字符串 格式:cin 字符串变量 cout 字符串变量,字符串连接运算 格式:字符串1 + 字符串2 功能:把连接运算符两端的字符连接成一个字符串。表达式

32、中可以用字符串常量也可以用字符串变量。 例:string st1=“C+”; string st2=“Language”; st1 = st1 + st2 ; 结果是 C+Language,字符串的比较运算 可以用关系运算符、=、=、!=、 “chinese” 运算结果是假。,1.4.11动态分配/撤销内存的运算符new和delete,分配内存运算 new 类型 (初值) 类型是决定分配空间尺寸的关键元素,如果运算结果正确,它的值是分配内存空间的起始地址,否则返回NULL。 例:int *a =new int ; int *b =new int( 100); char *ch = new ch

33、ar10; int * q = new int 54; float * p = new float(3.14159);,归还动态内存运算 delete 指针变量 代表数组,如果不是数组可以省略。 运算功能:撤销指针变量所指的动态内存空间,指针变量的数据类型决定了空间尺寸的大小。 例:char *p=new char10; delete p;,例1.18用动态内存存放结构体变量 #include #include using namespace std; struct student char name 10; int num; char sex; ;,int main ( ) student

34、*p; p=new student; strcpy(p-name,Wang Fun); p-num=10123; p-sex=M; coutnamenumsexendl; delete p; return 0; ,先声明了一个结构体类型student,定义一个指向它的指针变量p,用new开辟一个空间存放一个student类型变量。 如果无法正常分配内存,运算会返回一个空指针NULL,程序可以设计判断结构,根据判断结果决定怎样操作。 注意不要混合使用new、delete、malloc、free。要正确搭配,不要用new分配内存后,又用free释放内存。,1.5 C+程序的编写和实现,1. 用C+

35、语言编写程序 2. 对源程序进行编译 3. 将目标文件连接 4. 运行程序 5. 分析运行结果,第2章 类和对象,2.1 面向对象程序设计方法概述 2.2 类的声明和对象的定义 2.3 类的成员函数 2.4 对象成员的引用 2.5 类和对象的简单应用 2.6 类的封闭性和信息隐蔽,2.1面向对象程序设计方法概述,对于规模比较小的程序,程序员可以直接编写出一个面向过程的程序,能详细地描述每一瞬间的数据结构和对其操作的过程。但是当程序规模越来越大,面向过程的程序语言就显得力不从心,面向对象程序设计语言就应运而生,C+ 就是其中的一个成员。,2.1.1 什么是面向对象的程序设计 2.1.2 面向对象

36、程序设计的特点 2.1.3 类和对象作用 2.1.4 面向对象的软件开发,2.1.1什么是面向对象的程序设计,面向对象的程序设计的思路与人们日常生活中处理问题的思路是相似的。一个复杂的事物总是由许多部分组成的。例如,一辆汽车是由发动机、底盘、车身和车轮等部件组成。 当人们生产汽车时,不是先设计和制造发动机,再设计和制造底盘,然后设计和制造车身和车轮,而是分别设计和制造发动机、底盘、车身和车轮,最后把它们组装起来。这就是面向对象的基本思路。,1. 对象,客观世界中任何一个事物都可以看成一个对象。对象可以是自然物体,也可以是社会中的一种组织结构(班级、系、学校)甚至一个图形、一项计划等都可以看成对

37、象。复杂的对象由简单的对象组成,例如火车站对象包含售票处、行李房、候车室和站台、信号灯、铁轨和通信设施等对象。对象是构成系统的基本单位。任何一个对象都具有静态和动态的特征。,班级这个对象具有从属一个系和专业、学生人数、组建时间等静态特征,它还具有出操、学习、参加运动会等动态特征。静态特征称为属性,动态特征称为行为,外界给对象发出的信息一般称作消息。 一个对象往往包含一组属性和一组行为。如电视机包括生产厂家、品牌、屏幕尺寸等是静态特征,开机、关机、选择频道、调节音量、调节彩色等是动态特征。,面向对象的程序设计在设计一个系统时,首先要确定系统中包括哪些对象,要分别设计这些对象。在C+ 中,每个对象

38、由数据和函数(操作代码)两部分组成。数据代表了属性,函数是对数据操作的代码,代表了行为。例如三条边长是三角形的属性,利用三条边长计算三角形面积、输出计算结果,实现这些操作的代码就是对象的行为,在程序设计中又称方法。调用对象中的函数就是向对象传递一个消息,要求对象执行某个操作。,2. 封装与信息隐蔽,对一个对象进行封装处理,把它的一部分属性和功能向外界屏蔽,从外面看不到这些属性和功能。例如录像机里有电路板和机械控制部件,由于有机壳的保护,在外面只看到一个黑箱子,在它的表面有若干个按键。人们只需知道这些按键的功能即可操作录像机。而不必知道录象机的工作原理和系统结构。,在设计一个对象时,要周密地考虑

39、如何进行封装,把不必让外界知道的部分隐蔽起来。也就是说,把对象的内部实现和外部行为分隔开来。 封装性是面向对象程序设计的一个重要特点,封装在此有两个含义: 把有关的数据和操作代码封装在一个对象中,形成程序中的一个基本单位,各个对象之间相互独立,互不干扰。,把对象中的某些部分对外隐蔽,只留下与外界联系的接口接收外界的消息,这种对外界隐蔽的做法称为信息屏蔽。封装把对象内部实现与外部分隔开,外界不了解对象内部的具体细节,其实外界也不需要了解。外界需要真正了解的是对象的对外接口。C+ 对象中的公有函数就是对象的对外接口。外界通过调用公有函数,访问对象中的数据成员,完成指定的操作。,3. 抽象,抽象是表

40、示同一类事物本质的方法,它关注事物本质特征,对象是具体的,例如某学院2006级计算机软件专业的一个学生是一个对象,可以将一组同类对象的共同特征抽象出来,从而形成类的概念。可以将前面所提的某学院2006级计算机软件专业的所有学生可抽象出2006级计算机软件专业学生类。类是对象的抽象,而对象是类的具体实例。,4. 继承与重用,如果已经建立名为A 的类,现要建立一个名为 B 的类,而B 类与A 类的内容基本相同,只是在 A 类基础上增加了一些属性和行为,这样只需在 A 类的基础上添加新内容即可,这就是面向对象程序设计中的继承机制。 C+也具有继承机制,利用这个机制可以在一个已有的类的基础上建立一个新

41、类,这也是软件重用思想,不仅可以利用自己过去建立的类,而且还可以利用其他人放在类库中的类建立类,这就大大缩短了软件开发周期。,5. 多态性,多个相似而不完全相同的对象,收到外界给的同一个消息时,它们各自执行不同的操作,这种现象叫多态现象。 例如在windows中,用鼠标双击一个文件对象时,如果它是可执行文件则会执行文件中的程序,如果它是一个文本文件则会启动一个编辑器来打开这个文件,这就是面向对象程序设计中的多态性一个实际例子。 在C+中所谓多态性是指:由继承而产生的新类,它的对象对同一个消息会作出不同的响应。,2.1.2面向对象程序设计的特点,图2.3,传统的面向过程程序设计是围绕功能进行的,

42、用一个函数实现一个功能,一个函数可以使用任何一组数据,一组数据可以被多个函数使用。当程序规模越来越大,数据越来越多,操作越来越复杂,这种方法容易出现错误,程序员往往感到难以应付。,面向对象程序设计采用的是另外一种思路。它面对的是一个个对象。实际上每组数据都有特定的用途,它是某种操作的对象。也就是说,一组操作调用一组数据。例如三角形的三条边长 a、b、c 它们只与计算该三角形的面积、三角形的周长等操作有关,与其他操作无关。我们把这三个数据和计算三角形面积、周长等操作的代码放在一起,封装成一个对象,与外界相对分隔。这也符合客观世界的本来面目。,面向对象程序设计包括两个方面: 设计所需的各种类,即决

43、定把哪些数据和操作封装在一起。 考虑怎样向对象发送消息(调用对象的成员函数),实现所需的操作。这时设计程序象一个总调度,不断地向各个对象发送消息(命令),让这些对象活动起来(激活这些对象),完成各自的职责范围工作,各个对象的操作完成,整体任务也就完成了。,2.1.3 类和对象的作用,类是C+中十分重要的概念,它是实现面向对象程序设计的基础。C+ 对C改进,其中最重要的就是增加了类这样一种类型。类是所有面向对象的语言的共同特征,所有面向对象的语言都提供了这种类型。一个有一定规模的C+程序是由许多类构成的。可以说类是C+的灵魂。 C+支持面向过程的程序设计,也支持基于对象和面向对象的程序设计。从本

44、章到第四章介绍基于对象的程序设计。包括类和对象的概念、类的机制和声明、对象的定义与使用等。这是面向对象程序设计的基础。,基于对象就是基于类,基于对象的程序是以类和对象为基础的,程序的操作是围绕对象进行的。在此基础上利用继承机制和多态性,就成为面向对象的程序设计。 基于对象程序设计所面临的是一个个对象。所有的数据分别属于不同的对象。面向过程的程序设计中数据可以是公用的或者说是共享的,是缺乏保护的。缺乏保护的数据容易导致程序失败。其实程序中一组数据是为一种操作准备的,也就是说一组数据与一种操作对应。因此把一组数据和相关的操作放在一起,这就是面向对象程序设计中的对象。,在面向过程的结构化程序设计中,

45、人们用下面的公式描述程序: 程序=数据结构+算法 算法和数据结构两者是相互独立的,是分开设计的。面向过程的程序设计是以数据结构为基础的算法设计。在实践中人们逐渐认识到算法和数据结构是互相紧密联系不可分的。应当以一个算法对应一组数据结构,而不宜提倡一个算法对应多组数据结构,以及以一组数据结构对应多个算法。基于对象和面向对象程序设计就是把一个算法和一组数据结构封装在一个对象中,形成了新的观念:,对象=数据结构+算法 程序=(对象+对象+对象)+消息 消息的作用就是对对象进行控制。程序设计的关键是设计好每个对象,以及确定向这些对象发出的命令,让各个对象完成相应的任务。,2.1.4 面向对象的软件开发

46、,1. 面向对象分析 2. 面向对象设计 3. 面向对象编程 4. 面向对象测试 5. 面向对象维护,1.面向对象分析,面向对象分析,要按照面向对象的概念和方法,在对任务的分析中,从客观事物和事物之间的关系归纳出有关对象(对象的属性和行为)以及对象之间的联系。并将具有相同属性和行为的对象用一个类来表示。,2.面向对象的设计,根据面向对象分析阶段形成的需求模型,对每一部分分别进行具体的设计,首先是进行类的设计,类的设计可能包含多个层次(利用继承和派生机制)。然后以这些类为基础提出程序设计的思路和方法,包括了算法的设计。在此设计阶段,并不牵涉某一具体的计算机语言。,3.面向对象编程,根据面向对象设

47、计的结果,用一种计算机语言把它写成程序。 C+ Dephi VB Java,4.面向对象测试,写完程序交付用户使用前,必须对程序进行严格的调试,如果发现错误,要及时改正。 面向对象测试,是以类作为测试的基本单元用面向对象的方法实施测试。,5. 面向对象维护,任何软件产品在使用过程中,可能用户需要改进软件的性能,这就需要修改程序。由于采用了面向对象的方法,方便了维护程序。因为类的封装性,修改一个类对其他类(非子类)影响很小,极大提高了程序维护的效率。,2.2 类的声明和对象的定义,在面向对象程序设计中,要使用大量的对象,要程序员对问题进行分析抽象出类的概念,在设计程序时首先要声明类类型,然后再定

48、义类类型变量即对象。,2.2.1 类和对象的关系 2.2.2 声明类类型 2.2.3 定义对象的方法 2.2.4 类和结构体类型的异同,2.2.1类和对象的关系,2.1节已经说明了什么是对象。C+中对象的类型称为类(class)。类代表了某一批对象的共性和特征。类是对象的抽象,而对象是类的具体实例。正如结构体类型与结构体变量的关系一样,(先声明一个结构体类型,然后用它定义结构体变量)在C+ 中也是先声明一个类类型,然后用它定义同类型的对象。对象是类类型的一个变量。类是抽象的,不占用内存空间。对象是具体的,要占用内存空间。,2.2.2 声明类类型,类是要用户自己定义的类型,如果程序里要用类类型,

49、程序员必须自己根据需要声明,也可以使用别人已设计好的类。声明一个类类型与声明一个结构体类型相似。 struct student int num; char name20; char sex; ; student st1,st2;,Class student int num; string name; char sex; void setdata() cin num; cin name; cin sex; void display() cout numendl; cout nameendl; cout sex endl; ; Student st1,st2;,可以看到声明类的方法是由声明结构体类

50、型的方法发展而来。用上面的方法声明的类类型表示其中的各个成员对外面隐蔽,外界不能调用里面的函数。在程序中无法执行对象st1、st2中的setdata、display函数,因为缺少对外的接口这样的类是无用的。所以不能把类中的所有成员与外界隔离,一般是把数据隐蔽,而把成员函数作为对外的接口。让外界发出命令,通知对象st1执行display函数,输出该对象的数据。,类定义格式: Class 类名 private: 私有成员声明 public: 公有成员声明 protected: 保护成员声明 ;,class是保留字,声明类类型 类名:按标识符取名。 private、public、protected也

51、是保留字,是成员访问限定符,其后必须跟冒号。 在类声明的 后如不直接定义对象就必须跟分号。,private:只能被本类中的成员函数访问,类外(除友元外)不能访问。 public:公有成员可以被本类的成员函数访问,也能在类的作用域范围内的其他函数访问。 protected:受保护成员可由本类的成员函数访问,也能由派生类的成员函数访问。 在定义类时,这三类成员不分前后顺序,也可以重复出现。一般推荐最多出现一次。,2.2.3 定义对象的方法,1. 先声明类类型,然后再定义对象 在声明类类型后,像定义变量一样定义对象。 (1) class 类名 对象名表 例: class student st1, s

52、t2; (2)类名 对象名表 例: student st1, st2;,2. 在声明类类型的同时定义对象,class 类名 private: public: 对象名表;,Class student int num; string name; char sex; public: void setdata() cin num; cin name; cin sex; void display() cout numendl; cout nameendl; cout sex endl; st1,st2;,3. 不出现类名,直接定义对象,class private: public: 对象名表; 这种方法在

53、C+中虽然是合法的,但不提倡使用。,在面向对象程序设计和C+程序中,类的声明和类的使用是分开的,类并不只为一个程序服务,人们常把一些常用的功能封装成类,并放在类库中。在实际程序开发中一般采用第一种方法,在小型程序中或声明的类只用于本程序时,也可采用第二种方法。 在定义对象后,编译程序在编译时会为对象分配内存空间,存放对象的成员。,2.2.4 类和结构体类型的异同,C+允许用struct定义一个类类型,为什么C+ 要这样做?这是设计C+ 语言时规定的一项原则:C+必须兼容C,让C程序不用修改就能在C+环境中使用。 两种定义方法还是有区别的: 用class声明的类如果不带成员访问限定符,所有成员默

54、认限定为private; 用struct声明的类如果不带成员访问限定符,所有成员默认限定为public。,2.3类的成员函数,在声明类时,必须定义了访问类数据成员的函数,称之类的成员函数。,2.3.1 成员函数的性质 2.3.2 在类外定义成员函数 2.3.3 内置函数 2.3.4 成员函数的存储方式,2.3.1 成员函数的性质,类成员函数是函数中的一种,成员函数可以访问本类中的所有成员。如果成员函数的成员访问限定符是public,则对象可以通过它访问类的其他成员;如果是private或protected,则对象不能用来访问类的其他成员。 一般方法是把需要与外界沟通的成员函数指定为public

55、,作为类与外界的接口。,2.3.2在类外定义成员函数,C+允许在类内声明成员函数的原型,然后在类外定义成员函数。 格式 类型 类名:函数名(形参表) 成员声明 ,Class student int num; string name; char sex; public: void setdata() void display() ;,void student : setdata() cin num; cin name; cin sex; void student : display() cout numendl; cout nameendl; cout sex endl; student st1

56、,st2;,在类外定义成员函数时,必须在函数中增加类名,用于限定它属于哪个类,:是作用域限定符或称作用域运算符。上面的例子中如果函数不用成员访问限定符,函数就成了全局作用域中的display函数而不是成员函数。 如果在:前不带类名,或函数名前既无类名又无作用域运算符:,表示该函数是全局函数。,2.3.3 inline 成员函数,C+默认在类内定义的成员函数是inline函数,如果在类外定义成员函数时,系统默认不把它当作inline成员函数,此时必须在声明函数时在函数前加inline关键字。 在下面的例子中在函数声明里,函数头未加inline,C+将把它当作非inline函数。,Class st

57、udent int num; string name; char sex; public: void setdata() void display() ;,void student : setdata() cin num; cin name; cin sex; void student : display() cout numendl; cout nameendl; cout sex endl; student st1,st2;,如果要把它作为inline函数,只需在函数声明时,在函数头增加关键字inline。 class student int num; string name; char sex; public: inline void setdata() inline void display() ;,2.3.4 成员函数的存储方式,用类定义对象时,系统为每个对象分配内存空间,同一类对象的成员函数是一样的如果每个对象成员函数都分配内存空间,会造成大量浪费。,图2.4,C+ 处理的方法是,只为对象的数据成员分配内存空间,一个类的所有对象共享一个成员函数空间。,图2.5,如果声明一

温馨提示

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

评论

0/150

提交评论