C++程序设计(自考独立本科段)_第1页
C++程序设计(自考独立本科段)_第2页
C++程序设计(自考独立本科段)_第3页
C++程序设计(自考独立本科段)_第4页
C++程序设计(自考独立本科段)_第5页
已阅读5页,还剩124页未读 继续免费阅读

下载本文档

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

文档简介

C++程序设计课程代码4737任课老师:唐春艳Telmail:tangchunyan@1a第一章认识C++的对象第二章从结构到类的演变第三章函数和函数模板第四章类和对象第五章特殊函数和成员第六章继承和派生第七章类模板与向量第八章多态性和虚函数第九章运算符重载及流类库第十章面向对象设计实例2a第一章认识C++的对象3a需要了解的C语言知识C语言基本语法基本数据类型scanfprintf语句ifelse语句for语句while语句数组定义函数定义指针结构体运算符4a本节要点:C与C++的关系(领会)掌握函数原型和命名空间的使用方法(综合应用)对象和预处理基本概念(领会)掌握C++程序的基本结构(综合应用)1.1初识C++的函数和对象5aC语言回顾intx;

该语句在C语言和C++中均可使用,x在C语言中称为变量,在C++中称为对象。

C语言与C++的不同点:称呼不同6aC语言回顾结构体的定义structpoint{floatx;

floaty;};

表示定义一种点数据类型,包含坐标x,y.定义完成后,point成为一种类型,使用方式类似int类型如:定义p1变量为点类型,写作:structpointp1;或pointp1;定义x变量为整型:intx;7aC语言回顾结构体的定义structstudent{intnum;charname[10];

floatgrade;};

若定义一种结构体记录学生信息包含学号,姓名,成绩,如何定义?定义s1变量为学生类型,写作:structstudents1;8a#include<iostream>usingnamespacestd;intresult(int,int);constintk=2;structPoint{intx,y;};intmain()//主程序

{intz(0),b(50);Pointa;

cout<<“Inputtwointerger:”;cin>>a.x>>a.y;z=(a.x+a.y)*k;z=result(z,b);

cout<<“resultis:”<<endl;cout<<“z=“<<z<<endl;return0 }intresult(inta,intb){returna+b;}/*1-1.cpp*/#include<stdio.h>intresult(int,int);#definek2structPoint{intx,y;};intmain() /*主程序*/{ intz=0,b=50;Pointa;

printf(“Inputtwointerger:”);scanf(“%d%d”,&a.x,&a.y);z=(a.x+z.y)*k;z=result(z,b);

printf(“resultis:”);printf(“z=%d\n“,z);return0 }intresult(inta,intb){returna+b;}//1-1.c9a第一章认识C++的对象1.1初识C++的函数和对象例1.1输入一个点的信息,求该点到原点的距离预处理命令,使用命名空间,声明函数,声明常量,定义结构体,主函数main求距离函数result10a例1.111a例1.1主函数12a例1.113a对程序的说明:1,混合型语言C语言程序包含main函数面向对象语言没有main函数C++是混合型语言C++兼容C的语法,带类的C文件扩展名cpphmain()14a对程序的说明:2,注释方式/*。。。。*///。。。。15a对程序的说明:3,输入输出流cin和cout是C++语言中进行输入输出操作的函数。其定义在isstream头文件中。类似:C语言中printf函数scanf函数putchar函数getchar函数,使用时要包含“stdio.h”16aC++将数据从一个对象传到另一个对象称为流。cout是C++中的标准输出流(通常为控制台,即屏幕),cout<<“helloc”

把一串字符串插入输出流(控制台输出)中。<<是插入操作符。

cin是C++中的标准输入流(通常为控制台,即键盘),cin>>a.x>>a.y;将键盘输入的值赋予两个变量>>是提取操作符。cin,cout在的声明在头文件iostream中,所以要想使用cout必须将该头文件包括在程序开始处。17a对程序的说明:3,输入输出流cin和cout的简单使用cout<<后加要输出的内容,可以是对象或字符串,行末加分号,可用多个<<来分隔多个输出对象,<<endl;表示输出后换行。cout<<endl;等价于cout<<“\n”;18a对程序的说明:3,输入输出流cin和cout函数的简单使用cin>>后加存放数据的对象,即变量,行末加分号,可用多个>>来分隔多个输入对象。cin>>x>>y;等价于cin>>x;cin>>y;19a对程序的说明:4,使用命名空间是C++语言中封装程序库名称的一种机制记忆:C++标准类库中的对象和函数都属于std命名空间使用这些对象和函数时要usingnamespacestd;20a对程序的说明:4,使用命名空间使用std命名空间时注意:使用C语言中的头文件时,要写成“xxx.h”形式使用C++中的头文件则不能加上“.h”21ausingnamespacestd;C++标准函数库的所有元素都被声明在一个名空间中,这就是std名空间。因此为了能够访问它的功能,我们用这条语句来表达我们将使用标准名空间中定义的元素。这条语句在使用标准函数库的C++程序中频繁出现,本教程中大部分代码例子中也将用到它。22a所谓namespace,是指标识符的各种可见范围。

C++标准程序库中的所有标识符都被定义于一个名为std的namespace中。

由于namespace的概念,使用C++标准程序库的任何标识符时,可以有三种选择:

1、直接指定标识符。例如std::ostream而不是ostream。完整语句如下:

std::cout<<std::hex<<3.4<<std::endl;

2、使用using关键字。

usingstd::cout;

usingstd::endl;

以上程序可以写成

cout<<std::hex<<3.4<<endl;

3、最方便的就是使用usingnamespacestd;

例如:

#include<iostream>

#include<...>

usingnamespacestd;

这样命名空间std内定义的所有标识符都有效。就好像它们被声明为全局变量一样。那么以上语句可以如下写:

cout<<hex<<3.4<<endl;23a对程序的说明:5,对象定义及初始化intx;x=0;等价于intx=0;C语言intx(0);C++语言等价于上两条语句。此种初始化语法在C++中称为构造函数语法24a对程序的说明:6,函数原型及其返回值函数要有类型,若要得到处理结果则要使用return语句。floatresult()指出result是浮点类型,返回值由return后面的表达式决定,且表达式必须与声明函数的类型一致。25a对程序的说明:6,函数原型及其返回值函数原型声明函数调用在函数定义之前时要对函数进行声明26a27a例:intresult(int,int);C++要求所有函数都有函数原型程序的顶部头文件函数类型应和返回值的类型一致。C++提供更强的类型检查,允许编译程序对下列情况报错误信息:被调用函数参数类型定义和类型转换非法函数的参数个数不相符函数不能返回预定的数据类型28a对程序的说明:7,const修饰符和预处理程序常量定义:#definePI3.1415(c语言)在变量定义之前加上const关键字,表示定义的变量值不可改变。constintPI=3.1415;constintPI(3.1415);29a对程序的说明:7.const修饰符和预处理程序C++预处理命令以#开始,分为宏定义,文件包含和条件编译如:#define,#include,#if,#else,#elif,#endif,#ifdef,#ifndef,#undef等作业:1,写出C语言中预处理命令有哪些,举例说明每个命令含义及作用。2,写出C语言和C++语言中#include命令的不同处30a常量(constant)是一个有固定值的表达式。(1)#definePI3.14159265

#definetab'\n'

#definewidth100

(2)通过使用const前缀,你可以定义指定类型的常量,就像定义一个变量一样:constintwidth=100;

constchartab='\t';

constintwidth(100);constintwidth;extenconstintwidth;31a

对程序的说明:

8.程序运行结果32a

9.程序书写规则注意缩进对齐:程序块要采用缩进对齐风格编写,缩进的空格数为5个,使程序清晰明了。括号紧跟在函数名后,但在for和while后面,应用一个空格与左括号隔开以增加可读性。在两个以上的关键字、变量、常量进行对等操作时,它们之间的操作符之前、之后或者前后要加空格;进行非对等操作时,如果是关系密切的立即操作符(如->),后不应加空格。在表示参数时,逗号后面留一个空格。在for、do…while和while语句中,合理使用缩进、花括号和空行。适当增加空行和程序注释以增加可读性。一般情况下,源程序有效注释量必须在20%以上。较长的语句(>80字符)要分成多行书写,长表达式要在低优先级操作符处划分新行,操作符放在新行之首,划分出的新行要进行适当的缩进,使排版整齐,语句可读。33a1.2认识C++语言面向过程编程的特点本节要点:函数重载(领会)掌握C++的新数据类型(简单应用)动态分配内存(综合应用)熟练掌握引用的使用方法(综合应用)了解对指针使用const限定符的目的,方法(识记)了解泛型算法应用于普通数组的方法(识记)掌握数据的简单输入输出(简单应用)34a1.2认识C++语言面向过程编程的特点1.2.1函数重载(领会)C++允许一个函数定义多个版本。使得一个函数完成多种功能。即:同一个函数名定义多次。35a函数具有相同的名字,但有不同的参数,完成不同的操作和功能。重载函数至少在参数的个数、参数的类型、或参数的顺序上有所不同。//overloadedfunction

#include<iostream>

usingnamespacestd;intdivide(inta,intb){

return(a/b);}floatdivide(floata,floatb){

return(a/b);

}intmain(){

intx=5,y=2;

floatn=5.0,m=2.0;

cout<<divide(x,y);

cout<<"\n";

cout<<divide(n,m);

cout<<"\n";

return0;

}36a重载函数max的定义形式:37a重载函数max的声明形式:重载函数的要点:函数名相同,参数个数不同,参数类型不同38a重载函数max的调用形式:39a1.2.2C++的新数据类型(简单应用)1,void类型void表示无类型,或空类型。不能声明变量,只能声明函数返回值。表示函数无返回值。40a2,bool型(逻辑型,布尔型)占1个字节。表示逻辑运算中的“真”“假”3,整型(intlongshort)int、short至少16位long至少32位short不得比int长int不得比long长41a4,char型(字符型)占1个字节。5,实型(float/double/longdouble)42a5,&取地址符intx;&x表示????什么样的变量可以存放&x?????int*p;p是指针变量,指针变量能存放变量的地址。P=&x;43a6,常量表示整型:0前缀表示8进制数,0x前缀表示16进制加L、l后缀表示长整型常量实型:F、f后缀表示浮点型常量(float)实数加L、l后缀表示longdouble型无前缀,无后缀的为double型44a6,常量表示0L123l0550x50xaf017,转义字符‘\101’‘\t’‘\r’‘\n’‘\0’‘\x41’45a变量定义可以位于程序中的任何地方for(inti=0;i<10;i++){intc;c*=2;ints;……}46a1.2.3动态分配内存(综合应用)

到目前为止,我们的程序中我们只用了声明变量、数组和其他对象(objects)所必需的内存空间,这些内存空间的大小都在程序执行之前就已经确定了。但如果我们需要内存大小为一个变量,其数值只有在程序运行时(runtime)才能确定,例如有些情况下我们需要根据用户输入来决定必需的内存空间,那么我们该怎么办呢?答案是动态内存分配(dynamicmemory),

为此C++集成了操作符new和delete。47a1.2.3动态分配内存(综合应用)new动态分配内存一般格式:指针变量=new类型[size];

new运算符得到新分配空间的首地址,赋值给指针变量后,可根据指针变量的加减运算来使用这些空间。delete释放内存使用完毕后要释放内存deletep;48a

操作符new的存在是为了要求动态内存。new后面跟一个数据类型,并跟一对可选的方括号[]里面为要求的元素数。它返回一个指向内存块开始位置的指针。其形式为:p=new类型名;用来给一个单元素的数据类型分配内存。p=new类型名[SIZE];用来给一个数组分配内存。P+3pP+1操作符new和new[]49a给一个数组分配内存/*malloc.c*/inta[10],*p=a,i;for(i=0;i<10;i++)scanf(“%d”,p+i);for(i=0;i<10;i++)printf(“%d”,*(p+i));//new.cppint*p,k;cin>>k;//k=10p=newint[k];for(inti=0;i<k;i++)cin>>*(p+i);for(i=0;i<k;i++)cout<<p[i]<<“

“;delete[]p;50a给一个单元素的数据类型分配内存#include<iostream>usingnamespacestd;structPoint{intx,y;};intmain()//主程序

{ Point*p;

p=newPoint;

cout<<“Inputtwointerger:”;cin>>p->x>>p->y;cout<<p->x<<p->y;deletep;return0;}#include<stdio.h>structPoint{intx,y;};intmain() /*主程序*/{ Pointa*p;p=&a;

printf(“Inputtwointerger:”);scanf(“%d%d”,&a.x,&a.y);printf(“%d%d”,a.x,a.y);return0; }51a

删除操作符delete

既然动态分配的内存只是在程序运行的某一具体阶段才有用,那么一旦它不再被需要时就应该被释放,以便给后面的内存申请使用。操作符delete因此而产生,它的形式是:deletepointer;delete[]pointer;第一种表达形式用来删除给单个元素分配的内存,第二种表达形式用来删除多元素(数组)的内存分配。在多数编译器中两种表达式等价,使用没有区别,

52a1.2.4引用的使用方法(综合应用)C++中新的表示形式。引用即使用变量的别名。定义形式:数据类型&别名=对象名;作用:别名与对象名对应同一个对象,共用同一段内存。对别名的修改会造成原对象的修改。例如:intx;int&a=x;表示a是变量x的别名。一旦定义别名后则a和x完全等价。53a1.2.4引用的使用方法(综合应用)C++中新的表示形式。引用即使用变量的别名。定义形式:数据类型&别名=对象名;54a引用是指给对象的地址取个别名,数据类型&别名=对象名(正名)

inta=56,b;int&ra1=a;int&ra2=ra1;

对别名的改动则是对正名的改动。引用只是将一个新标识符和一块已经存在的存储区域相关联,不占有存储空间,别名和对象(正名)占有相同存储空间55a引用作为函数参数--地址传递不能直接声明对数组的引用不能声明对引用的引用

int&&r=x;可以声明对指针的引用。

intx,*p2=&x;int*&p1=p2;int*&p3=p2;p1=&x;intx=56;int&a=x;int*p=&x;int*p=&a;56a使用引用时注意:1,不能定义引用的引用int&&r=x;2,不能直接定义数组的引用57a1.2.4引用的使用方法(综合应用)一般格式:typedef类型类型别名使用typedef定义某类型别名后,可使用该别名来定义相关对象。例如:typedeflongintlint;则longinti;

等价于linti;Typedef使用说明typedef用法总结:建立一个类型别名的方法很简单,在传统的变量声明表达式里用类型别名替代类型名,然后把关键字typedef加在该语句的开头58a等价于间接引用数组名作参数array&b=x;array&b=x;59a60a例1-4#include<iostream>usingnamespacestd;voidmain() { intx=56;int&a=x; int&r=x;cout<<"x="<<x<<"&x="<<&x<<endl;cout<<"a="<<a<<"&a="<<&a<<endl;cout<<"r="<<r<<"&r="<<&r<<endl;r=78;cout<<"afterr=78"<<endl;cout<<"x="<<x<<"&x="<<&x<<endl;cout<<"a="<<a<<"&a="<<&a<<endl;cout<<"r="<<r<<"&r="<<&r<<endl;}61a例1-5间接引用数组#include<iostream>usingnamespacestd;typedefintarray[10];voidmain() {arraya={1,2,3,4,5,6,7,8,9,10};array&b=a;b[9]=0;cout<<"b[10]"<<endl;for(inti=0;i<10;i++)cout<<b[i]<<"";cout<<endl;cout<<"a[10]"<<endl;for(i=0;i<10;i++)cout<<a[i]<<"";cout<<endl;}62a1.2.5对指针使用const限定符(识记)1,左值和右值表达式:E1=E2

E1是左值,是可被修改的int*p,x=1;p=&x;*p=2;&p表示什么?63a1.2.5对指针使用const限定符(识记)2,指向常量的指针const常量定义,表示const后的表达式不可改变,定义时必须给出表达式的值。intx=11;constint*P;constint*P=&x;表示*P是不可改变的。*P不能在=左侧。P=&y;x=12;constint*p;表示*p是常量,不能被赋值,

*p=66;64a2.指向常量的指针#include<iostream>usingnamespacestd;voidmain() {constinty=58;constint*p=&y;intx=45,z;constint*p1=&x;z=*p1+*p;cout<<"z="<<z<<endl;p1=&y;//*p1=y;z=*p1+*p;cout<<"z="<<z<<endl;}65a1.2.5对指针使用const限定符(识记)3,常量指针const常量定义,表示const后的表达式不可改变,定义时必须给出表达式的值。intx=11;int*constP;错!必须初始化int*constP=&x;表示P是不可改变的。P不能在=左侧。*p可改变。66a3,常量指针intx=45,y;int*constp=&x;表示p是常量,需要初始化p不能被赋值,p=&y;#include<iostream>usingnamespacestd;voidmain() { inty=58,x=66;int*constp=&y;cout<<“y="<<y<<endl;*p=66;//p=&x;cout<<“y="<<y<<endl;}67a1.2.5对指针使用const限定符(识记)4,指向常量的常量指针const常量定义,表示const后的表达式不可改变,定义时必须给出表达式的值。intx=11;constint*constP=&x;表示P是不可改变的。*p不可改变。68a1.2.6泛型算法应用于普通数组(识记)泛型算法是C++标准模板库(StandardTemplateLibrary)提供的一组操作。利用这些操作可以简化数组操作。要使用这些操作必须包含头文件<algorithm>69a1.2.6泛型算法应用于普通数组(识记)假定a,b是两个数组名,其长度为len操作示例:1,reverse(a,a+len)将数组a中的元素顺序反转。(逆向)2,copy(a,a+len,b)将a数组的内容原样复制给b数组3.reverse_copy(a,a+len,b)将a数组的内容反转后复制给b数组70a1.2.6泛型算法应用于普通数组(识记)假定a,b是两个数组名,其长度为len操作示例:reverse_copy(a,a+len,b)3,sort(a,a+len)将数组a中的元素按升序排序4,sort(a,a+len,greater<type>())将数组a中的元素按降序排序71a1.2.6泛型算法应用于普通数组(识记)5,find(a,a+len,value)在数组a中查找值为value的元素,并返回位置指针假定a,b是两个数组名,其长度为len操作示例:find(a,a+len,4)72a1.2.6泛型算法应用于普通数组(识记)6,输出数组中的内容Copy(a,a+len,Ostream_iterator<type>(cout,”字符串”))Ostream_iterator表示输出流操作符<type>:表示要输出的数组类型Cout表示流输出操作“字符串”:表示分隔字符串73a例1-6数组升幂排序、复制、输出#include<iostream>#include<algorithm>usingnamespacestd;voidmain() {doublea[]={1.1,4.4,3.3,2.2},b[4];copy(a,a+4,ostream_iterator<double>(cout,""));reverse_copy(a,a+4,ostream_iterator<double>(cout,""));copy(a,a+4,b);copy(b,b+4,ostream_iterator<double>(cout,","));sort(a,a+4);copy(a,a+4,ostream_iterator<double>(cout,""));reverse_copy(a,a+4,b);copy(b,b+4,ostream_iterator<double>(cout,","));}74a例1-6数组升幂排序、复制、输出//p27-4#include<iostream>#include<algorithm>#include<functional>usingnamespacestd;voidmain() {inta[]={1,2,3,4,5,6,7,8},b[8];Cout<<Find(a,a+8,4);copy(a,a+8,b);reverse(a,a+8);Cout<<Find(a,a+8,4);copy(a,a+8,ostream_iterator<int>(cout,""));copy(b,b+8,ostream_iterator<int>(cout,","));}

75a1.2认识C++语言面向过程编程的特点1.2.7数据的简单输入输出格式(简单应用)输入输出格式控制有两种方法:1操作符函数<iostream><iomanip>2IOS—BASE接口76a例1.10#include<iostream>#include<iomanip>usingnamespacestd;voidmain(){inta=29,b=1001;cout<<a<<setw(6)<<b<<endl;cout<<setw(6)<<a<<b<<endl;cout<<setfill('*')<<a<<setw(6)<<b<<endl;cout<<setfill('#')<<setw(6)<<a<<b<<endl;cout<<"------------------"<<endl;cout<<setiosflags(ios_base::left);cout<<setw(10)<<b<<endl;cout<<setiosflags(ios_base::right);cout<<setw(10)<<b<<endl;}77a例1.11#include<iostream>#include<iomanip>usingnamespacestd;constdoublePI3.1415926oidmain(){cout<<PI<<endl;cout<<setprecision(0)<<PI<<endl;cout<<setprecision(3)<<PI<<endl;cout<<setprecision(7)<<PI<<endl;intb=100;cout<<"hex="<<hex<<b<<endl<<"oct="<<oct<<b<<endl<<"dec="<<dec<<b<<endl;cout<<setiosflags(ios_base::showpos)<<b<<endl;cout<<resetiosflags(ios_base::showpos)

<<b<<endl;78a第一章认识C++的对象1.3程序的编辑、编译、运行79a第一章认识C++的对象课后题:P26三、改错题写作业本上80a第2章从结构到类的演变81a2.1结构的演化结构由若干元素构成,C语言中称这些结构元素为结构成员,C++中称为数据成员。能够做数据成员的不只是基本数据类型的变量,还可以是构造类型(数组、指针甚至是其他类型的结构)变量。C++的结构中可以有函数。其实,类确实是从结构演变而来,开始称为“带类的C”。这场革命就是从让结构含有函数开始的。82a2.1.1结构发生质的演变1.函数与数据共存C++允许结构中可以定义函数,这些函数称为成员函数。如果将原来的结构成员称为数据成员的话,可以使用如下的形式描述:

struct结构名{

数据成员成员函数

};可以像结构变量或指针使用结构成员那样,使用成员函数:结构变量.成员函数指向结构变量指针的名字->成员函数83a假设为结构Point设计一个Setxy函数如下:

voidSetxy(doublea,doubleb){x=a;y=b;}

如果把域x和y称为结构的数据成员,则可以使用参数表中的a和b赋给结构变量的数据成员。假设有对象(结构变量)a,则语句:

a.Setxy(12.5,14.5);使结构变量a的a.x=125,a.y=14.5。84a【例2.1】结构中使用成员函数的实例。#include<iostream>usingnamespacestd;structPoint{doublex,y;//数据成员

voidSetxy(doublea,doubleb)//成员函数,用来重新设置数据成员

{x=a;y=b;}voidDisplay()//成员函数,按指定格式输出数据成员的值

{cout<<x<<"\t"<<y<<endl;}};85avoidmain(){

structPointa,*p;//定义变量和指针变量

a.Setxy(10.6,18.5);//设置变量a的数据成员

a.Display();//显示变量a的数据成员

p=&a;//使用变量a初始化指针变量

p->Display();//使用指向变量a的指针调用成员函数

cout<<p->x<<"\t"<<p->y<<endl;}程序运行结果如下:10.618.510.618.510.618.5

主程序中的变量是通过结构的成员函数使用数据成员,但最后一条语句则是直接使用数据成员。这称作结构Point的公有(public)性质。86a2.封装性所谓封装性,就是限制存取权限。如果在定义结构时,将数据成员使用private关键字定义,则产生封装性。

87a【例2.2】使结构具有封装性的实例。#include<iostream>usingnamespacestd;structPoint{

private:doublex,y;//数据成员

public:voidSetxy(doublea,doubleb)//成员函数用来重新设置数据成员

{x=a;y=b;}voidDisplay()//成员函数,按指定格式输出数据成员的值

{cout<<x<<"\t"<<y<<endl;}};

88a没有使用private定义的成员函数,默认为public(也可以直接使用public)。这时,如果还使用【例2.1】的主程序,则其最后一条语句就出现编译错误。也就是说,私有的数据成员,必须通过成员函数才能使用,这就称为数据的封装性。89a2.1.2使用构造函数初始化结构的对象因为【例2.2】的程序使结构具有封装性,所以不能使用初始化列表初始化结构对象。为此,这里为结构Point设计两个专门用于初始化的函数。这两个函数具有相同的名字Point,其原型如下:

Point();Point(double,double);这是函数重载。因为这里的函数名与结构同名,称为构造函数。构造函数专门用于初始化对象。90a【例2.3】使用构造函数初始化对象的实例。#include<iostream>usingnamespacestd;structPoint{private:doublex,y;//数据成员

public:Point(){};//无参数构造函数

Point(doublea,doubleb)//具有两个参数的构造函数

{x=a;y=b;}voidSetxy(doublea,doubleb)//成员函数,用来重新设置数据成员

{x=a;y=b;}

91a

voidDisplay()//成员函数,按指定格式输出数据成员的值

{cout<<x<<"\t"<<y<<endl;}};voidmain(){Pointa;//定义对象aPointb(18.5,10.6);//定义对象b并赋初值

a.Setxy(10.6,18.5);//设置变量a的数据成员

a.Display();//显示变量a的数据成员

b.Display();//显示变量b的数据成员}程序运行结果如下:10.618.518.510.692a

现在不深究构造函数的原理,只要记住它的使用方法即可。一般形式为:

构造函数名对象名(初始化参数);程序在运行时,会自动完成初始化任务。例如语句

Pointb(18.5,10.6);使得a.x=18.5,a.y=10.6。93a2.2从结构演变一个简单的类其实,使用关键字class代替struct,就是一个标准的类。【例2.4】定义类的实例。classPoint{

private:doublex,y;//类point的数据成员94apublic:Point(){};//类Point的无参数构造函数

Point(doublea,doubleb)//具有两个参数的构造函数

{x=a;y=b;}voidSetxy(doublea,doubleb)//成员函数,用来重新设置数据成员

{num=a;score=b;}voidDisplay()//成员函数,按指定格式输出数据成员的值

{cout<<x<<"\t"<<y<<endl;}};使用类产生对象的方式如结构一样,可以使用如下的主函数,将得到相同的运行结果。95avoidmain(){Pointa;//定义类Point的对象aPointb(18.5,10.6);//定义类Point的对象b并初始化

a.Setxy(10.6,18.5);//为对象a的数据成员赋值

a.Display();//显示对象a的数据成员

b.Display();//显示对象b的数据成员}程序运行结果如下:10.618.518.510.6可以将point类看作直角坐标系的点类96a2.3C++面向对象程序设计特点面向对象的程序设计方法要求语言必须具备抽象、封装、继承和多态性等关键要素。2.3.1对象现实世界中客观存在的事物为对象。复杂的对象可以由简单的对象组成,例如火车站对象又包含售票处、行李房、信号灯、站台、铁轨和通信设施等对象。这些对象各自又由许多对象组成,对象各自完成特定的功能。总之,世界万物皆对象。售票处有各种规格的车票,这些车票表示售票处的静态特征。它提供发售车票的功能(操作),表示了售票处的动态特征。97a通过这种抽象归纳,C++可使用对象名、属性和操作三要素来描述对象。对象名用来标识一个具体对象。用数据来表示对象的属性,一个属性就是描述对象静态特征的一个数据项。操作是描述对象动态特征(行为)的一个函数序列(使用函数实现),也称为方法或服务。数据称为数据成员,函数称为成员函数。由此可见,C++中的对象是系统中用来描述客观事物的一个实体,是构成系统的一个基本单位。一个对象由一组属性和对这组属性进行操作的成员函数构成。98a对象名属性1属性2……属性n操作1操作2……操作n图2.2对象结构图99a【例2.5】用简单对象表示平面上的A(3.5,6.4)和B(8.5,8.9)两个坐标点。可使用图2.3表示具体对象A和B的对象结构。

Bx(8.5)y(8.9)

display();setxy();move();Ax(3.5)y(6.4)

display();setxy();move();

对象名是“A”,A是一个点的对象。没有给对象A的属性赋值时,这只是个抽象名词。只有具有确定的属性值,才是一个具有确定位置的点。图中用x坐标和y坐标表示坐标点对象的静态属性(称为位置属性)。假设让点对象对外有显示属性值、设置属性值和移动位置等操作,这里分别使用成员函数display,setxy,move来实现这些操作。

100a2.3.2抽象和类抽象是一种从一般的观点看待事物的方法,即集中于事物的本质特征,而不是具体细节或具体实现。面向对象鼓励程序员以抽象的观点看待程序,即程序是由一组抽象的对象(类)组成的。可以将一组对象的共同特征进一步抽象出来,从而形成“类”的概念。例如,从点A和B抽象出点的概念,这就是“点类”。101aPointfloatx;floaty;display();setxy();move();图2.4类Point的结构图

102a

类由类名、一组属性和一组操作等3部分组成。类的属性只是性质的说明,对象的属性才是具体的数据。所以,图2.4的Point类只是表示类名是Point,它的点位置是两个实数,但还没有具体的位置。只有像本节A和B两点具有确定的属性值,才是Point类的具体对象,称它为类Point的一个实例。类名属性1属性2……属性n操作1操作2……操作n图2.5类模型的结构图

103a

对于一个具体的类,它有许多具体的个体,这些个体叫做“对象”。举个例子,“人”是一个类,具有“直立行走、会使用工具”等一些区别于其他事物的共同特征;而张三、李四、王五等一个个具体的人,就是“人”这个类的一个个“对象”,同一类的不同对象具有相同的行为方式(如张三和李四都能直立行走、会使用工具),不同类的对象具有不同的行为。类的作用是定义对象。类和对象的关系如同一个模具与用这个模具铸造出来的铸造件之间的关系。类给出了属于该类的全部对象的抽象定义,而对象则是符合这种定义的实体。所以,C++中将对象称做类的一个实例。104a

在程序中,每个对象需要有自己的存储空间以保存它们自己的属性值。所谓“一个类的所有对象具有相同的属性”,是指属性的个数、名称、数据类型相同,各个对象的属性值则可以互不相同,并且随着程序的执行而变化。至于操作,则是所有对象共同使用它们的类定义中给出的操作代码。105a消息(Message)对象之间相互请求相互协作的途径一个消息由下述三部分组成:(1)接收消息的对象;(2)消息选择符(也称为消息名);(3)零个或多个变元。例如:MyCircle.Show(GREEN)

;其中:

MyCircle是接收消息的对象的名字

Show是消息选择符(即消息名)

GREEN是消息的变元。

消息106a2.3.3封装将类封装起来,也是为了保护类的安全,所谓安全,就是限制使用类的属性和操作。按照面向对象的封装原则,一个对象的属性和操作是紧密结合的,对象的属性只能由这个对象的操作来存取。对象的操作分为内部操作和外部操作。内部操作只供对象内部的其他操作使用,不对外提供服务。外部操作对外提供一个消息接口,通过这个接口接收对象外部的消息并为之提供操作(服务)。对象内部数据结构的这种不可访问性称为信息(数据)隐藏。107a数据封装给数据提供了与外界联系的标准接口,无论是谁,只有通过这些接口,使用规范的方式,才能访问这些数据。同时,由于程序员总是和接口打交道,因此就不必了解数据的具体细节。简言之,封装就是把对象的属性和操作结合成一个独立的系统单位,并尽可能隐蔽对象的内部细节。

在类中,封装是通过存取权限实现的,如将每个类的属性和操作分为私有的和公有的两种类型。对象的外部只能访问对象的公有部分,不能直接访问对象的私有部分。108a2.3.4继承对象的另一个特点是继承。继承是一个对象可以获得另一个对象的特性的机制,它支持层次类这一概念,例如红香蕉苹果属于苹果类,而苹果类又属于水果类。通过继承,低层的类只须定义特定于它的特征,而共享高层的类中的特征。109a2.3.5多态性不同的对象可以调用相同名称的函数,并可导致完全不同的行为的现象称为多态性。利用多态性,程序中只须进行一般形式的函数调用,函数的实现细节留给接受函数调用的对象。这大大提高了我们解决复杂问题的能力。如将两个数“相加”,这两个数可以是整数或实数,将“+”看做一个特殊函数,则8+7和23.5+8.7都是使用“+”来完成两个数相加的功能,这就是“+”体现的多态性。由此可知,“-”、“*”和“/”也都具有这一特征,而且还可以自己定义这些运算符的功能。110a2.5熟悉并使用类和对象

本节将介绍如何使用C++标准程序库提供的string类和complex类,目的是进一步了解类和对象的概念,为以后自己编写类打下基础。

111a2.5.1使用string对象

C++标准程序库提供string类,string类可以像char那样定义一个字符串对象,但string类定义的对象不需要结束符“\0”,而且可以使用string类提供的成员函数进行相应操作,例如求字符串的长度或取这个字符串的子串等。

112a

图2.7string类的简化图stringstr

stringfindsizesubstr113a从图2.7可见,它的属性是一个字符串str,同名函数string是构造函数,用来初始化字符串,有参数不同的几种构造函数。另外3个成员函数用来对属性str进行操作。成员函数find用来在str字符串中检索所需要的子串;size成员函数计算并输出str存储的单词长度;substr成员函数,用来返回str字符串中的子串。114a在程序中可以使用string类定义存储字符串的对象。这些对象隶属于string类,因此还必须在程序中包含这个类的头文件,即使用语句#include<string>可以使用双引号括起来的单个字符常量初始化,即下面语句均是正确的:stringstr="A";stringstr("A");//也是正确的如果string的对象str的内容为“ab”,则str[0]='a',str[1]='b'。115a【例2.6】演示使用string对象及初始化的例子。#include<iostream>#include<string>usingnamespacestd;voidmain(){stringstr1("Wearehere!");stringstr2="Whereareyou?";cout<<str1[0]<<str1[11]<<",“<<str1<<endl;cout<<str2[0]<<str2[13]<<",“<<str2<<endl;cout<<"pleaseinputaword:";cin>>str1;cout<<"lengthofthe"<<str1<<"is"<<str1.size()<<"."<<endl;}116a下面是程序的输出结果:

W!,Wearehere!

W?,Whereareyou?pleaseinputaword:goodlengthofthefineis4.117a对象使用自己的成员函数的方法是通过“.”运算符,格式如下:

对象名.成员函数例如对象str1使用类string的size成员函数计算并输出单词的长度,其格式为:

str1.size()string类还提供将两个字符串连接起来组成一个新字符串的能力。“+”号将其后的字符串连接到前一个字符串的后面,也可以与单个字符常量相加。例如语句

str=str+''+str;将原来的两个str的内容用空格连起来,新内容为:

Wearehere!Wearehere!118a2.5.2使用string类的典型成员函数实例

string对象是通过调用成员函数实现操作,从而提供对象的行为或消息传递的。对象调用成员函数的语法可表示如下:

对象名称.成员函数(参数(可供选择的消息内容))例如string类提供的substr成员函数,用来返回字符串的子串。第1个参数是要截取子串在字符串中的位置,第2个参数是截取的长度。要从对象str中截取“are”,因为C++规定字符串的计数是从零开始的,所以“a”处于位置3,可用如下语句实现:

stringnewstr=str.substr(3,3);这时newstr的内容为“are”。119a给出的位置必须位于字符串中,否则出错。如果长度大于字符串的长度,则是可以的,它自动截取到末尾。

stringstrnew=newstr.substr(2,8);截取的内容为“e”,等同于语句“stringstrnew=newstr.substr(2,1);”。成员函数find用来在主串中检索所需字符串。它有两个参数,格式如下:

对象名称.find(要查找的字符串,开始查找的位置);该成员函数返回查找到的字符串在主串的位置。例如:

inti=str.find("are",0);表示从str字符串的位置0(起始位置)开始查找,结果为3。如果改从4开始,则查找到连接的第2个“are”,结果为16。如果让它从17处开始,则找不到,返回值为-1。如果不给位置参数,默认位置参数为0,即上述语句可写为

inti=str.find("are");120astring类还提供一个辅助功能,以便使用getline从流cin中读出输入的一行给string类的对象。

stringInputLine;getline(cin,InputLine,'\n');cout<<"yourinput:"<<InputLine<<endl;

如果输入“Iamhere!”,则得到如下结果:

yourinput:Iamhere!121a【例2.7】演示将美国格式的日期转换为国际格式的例子。美国使用月日年格式,例如May28,2002。转为国际格式应为28May2002。这可以使用find检索,使用substr截取,然后再按要求重组。具体步骤如下:①寻找月份。假设string类的Date对象存放美国日期,则下列语句inti=Date.find(“”);//查找May与28之间的空格,i=3stringMonth=Date.substr(0,i);//从0位置开始截取i个字符(上面求的i=3)得到Month。②寻找日子。寻找“,”号,假设其位置为k。Day的起始位置应是i+1处,长度应是k-(i+1),则语句

stringDay=Date.substr(i+1,k-i-1);得到Day。③寻找年份。年份应从逗号处再计数2次

温馨提示

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

评论

0/150

提交评论