




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第一章认识C§1.1CC.cppmain①从“/*”开始,到“*/”结束,如:/*…… cin>>②操作:用操作符“<<”向cout输出流中字符,如:cout cout<<前使用#includeiostream>将C++标准输入输出库头文件iostreamcout“\nC++相比C而言,可以省略“.h”标识头文件,但必须使用语句usingnamespacestd;来让命名空间中的对象名称。因此一般的程序都要具有#include usingnamespace 注意C++库中代替C库中头文件的正确名称,例如下面两个语句效果一①#include②#include<cmath>usingnamespacestd;Intz(0); //等同于intz=0;result(int,int;它向编译系统,后面有一个result函数,该函数有两如:intresult(inta,intb;和上面的效果一样。②除构造函数与析构函数外,函数都需要有类型如intmain(),main是整数类型,返回值由return后面的表达式如果函数确实不需要返回值,还可用void标识,一旦使用void标识,函③C++函数有库函数(标准函数,时函数名外加<>)和自定义函数(引)两类。①constCdefine”定义常量,而C++中除此外,建议使用const代替宏定义,用关键字const修饰的标识符称为符号常量。const#difineBOFSIZE100constintBUFSIZE100;constintk(2; constint因被const修饰的变量的值在程序中不能被改变,所以在符号常量时,必须对符号常量进行初始化,除非这个变量是用extern修饰的外部变量,如:constint constintd=2; externconstintconst的值不会改变,就应该用const来修饰这个变量,以提高程序安全性。CC++编译程序的一部分,它负责在编译程序的其预处理语句有三种:宏定义、文件包含(也成嵌入指令)引号也可以使用尖括号,前者自己定义的包含文件,如:#include“E:\prog\myfile.h”,后者系统提供的包含文件,如标准输入输出是定义在标准库iostream中的,时要包括以下两条语句:#include usingnamespace forwhile②数算符左右各留一个空格,以与表达式区别④在for、do…while和while§1.2C假设有一个函数maxintmax(int,int; max(int,int,int;//3只要分别为不同参数的max1、void是无类型标识符,只能函数的返回值类型,不能变量2、CC多了bool(布尔)3、C++只限定int和short16位,而long32shortint,intlong,VC++6.0int4C2如:intx=56;定义x,VC++6.0使用4个字节对象56,假设存放的内006AFDECcout&x;自动使用十六进制输出的首地址006AFDEC。5、C++中的常量分三种,第一种为符号常量;第二种为整数常量,有4种类第三种为浮点常量,有三种类型,分别为floatlongfloatdoubleF(f,如浮点常 L(l,常 double型:无后缀,如3.0、12.3、长整型:后缀L(l),如-456L0LL整数常 (oO(ox16、CC’\0’表示ASCII(NLL,’\’new类型名[size] //申请可以size个该数据类型的对象不再使用时,必须使用delete指针名;来释放已经申请的空间。double //double型指p=new //分配3个double型数据的空delete //释放已申请的空2、C必须在可执行语句之前集中变量,而C++可以在使用对象时再指针名=new结构名; 1.1的Pointp=new当不再使用这个空间时,必须使用deletep四、1、简单的说,就是为现有的对象起个别名,别名的地址与对象的的方式为:数据类型&别名=对象名;,注意对象在前必须先初始化,另外中符号“&”的位置无关紧要,比如int&a=x;、int&a=x;和int&a=x;等效。int int& //a是x的,二者地址相int //r是a的,二者地址相 rax2、所谓“,就是将一个新标识符和一块已经存在的区域相关联。因此,使用时没有分配新的区域,它本身不是新的数据类型。通常用于函数的参数表中或作为函数的返回值前者因为使用作为(§4.4.3,后者则是因为作为函数返回值可用于赋值运算符的左边。3、实际上就是变量的别名,使用就如同直接使用变量一样,与变量名在使用的形式上完全一样,只是作为一种标识对象的。但要注意,可以指向变量或的指针,如:int*p=&x;int&a=x;int*p=&a;√;也可以指针对指针的,如:int*&=p1;√(式中p1、p2是指针,*p2是指针,&p2是p1的;但不能指针对变量的,如:int*&P=&x;×;不能的,如:int&&r=x;×;也不能直接对数组的。、4的作用与指针有相似之处它会对内存地址上存在的变量进行修改,、5、虽然不能直接定义对数组的,但可以通过typedef来间接的建立对typedefint int型数组类型arraya={12,34,……}; //定义array型数组aarray& //定义数组a的pa*p变量,也就是变量a,且下面等式成立: 作为左操作数,也可作为右操作数,如:x=56;和y=x;,而右值56就只”也可产生左值,例如p“*p”是左值表达式,代表由p且可通过“*p=”&p”也是左值表达式,代表由p指向3、指向常量的指针(constint*p=&x;“*p=”的操作不成立它告诉编译器,*p是常量,不能将*p作为左值进行操作,即限定了“*p=”的constintconstint y,yintconstint x*p上式中*p不能作为左值,但可以通过“x=”改变x的值,间接改变*p的const*p*p4、常量指针(int*constp=&x;“p=”的操作不成立const*const,即常量intint*const个生存期中都不会改变,编译器把p=”不成立,也就是说不能改变指针p容可以使用间接运算符*改变其值,例如语句*p=56;将上面的x的值改变为56。intconstint*const语句告诉编译器,*p和p都是常量,都不能作为左值,即“*p=”和如inta[]={5,6,7,8};则数组中各元素分别为:a[0]=5,a[1]=6,a[2]=7,a[3]=8。a为数组句sort(a+1a+4;,只对从a+1(不含a+1)起到+4(a+4)a+2,a+3,a+4三个位置上的三个元素,而不是a+1~a+4四个位置上的所有4个元素。注意式中的a+1并不是地址a加上一个字节后的地址,而是a+1×d得到的地址,其中d是元素类型占用的字节数,比如C4则a+1位置上元素的地址就是地址a加上4个字节后得到的地址。2、数组不能作为整体输出,C++引入STL3、对数组内容进行升幂、输出、反转和等操作需要包含头文<algorithm>;对数组内容进行降幂和检索等操作需要包含头文件4abLenType,则对数组内everse(a,a+Len; ②数组内容copy(a,a+Len,b; //将数组a的内容原样到数组beverse_copy(a,a+Len,b;//逆向数组a中内容到数组bsort(a,a+Len; (b,b+Len,geater<ype>(find(a,a+Len,alue;//查找数组find函数返回的是位置指针,一般使用判别语句输出查找的内容,如:Type*x=find(a,a+Len,alue;//x是类型为typeif(x==a+Len)cout<<“没有值为value coutvalueyaaLnatty>t可将ostream_iteratorType>表示数组元素的数据nrscopy(a,a+Ln,ostamtrar<yp>(cout 排序:sort(默认升幂,尾部加greater<Type>()为降幂) 输出:ostatrator<Yyp(cot串1、C++提供了两种格式控制方式,一种是使用iso_base输出表达式中,因此更为方便,不带形式参数的操控符定义在头文件(设置浮点数输出精度ch设置flag清除flag两个操控符的参数flag是C++的类ios_base里定义的枚举常量,要使用ios_base定义的枚举常量,另外flag可由多个常量“或”起来使用,如:setiosflags(ios_base::showpoint|ios_base::fixed参数flag常的枚举常量及其含使用科学表示浮点cout<<setw(16)<<setfill(cout<<setw(16)<<setfill(‘*’)<<“
////<<setw(5)<<3<<endl;“*②使用setprecitionconstdoublevoid}3注意使用setprecition(intn1,1才显示小数点后面的一位数。因系统只输出5位小数,所以为了将6位小数全7③使用dec、oct、hexint <<”Inputb 100cout<<”Inputb=”; 100Input //因尚未转换基数,100Input 100 //清除flagcout<<oct100cout<<dec使用语句cout<<dec<<setiosflags(ios_base::showpos)<<b<<endl;除了将语句使用清除该设置标志的语句cout<<resetiosflags(ios_base::showpos);执stosags(iosas::howpos)§1.3①先使用编辑器编辑一个C++程序mycpp.cppC②然后使用C++编译器对这个C++程序进行编译,产生文件Link,将变成现在C++的编制一般都使用集成环境,如VisualC++6.0VC编制C①启动②File菜单-New框-Project选项卡-Win32ConsoleApplication选项,在右边的Projectname输入框中输入项目名称myfile,在右边的Location输入框中输入,然后单击OK按键,进入Win32ConsoleApplicationC++程序文件是选择Anemptyproject选项,单击Finish按钮,完成设置;③选中FileViewmyfilefilesSourceFileFile菜单中选newnew话框;选中C++SourceFile选项,在右方的File输入框中输入C++程序文(mycpp并在SourceFile项下面产生空文件mycpp.cpp;在右边的源代码编辑框中输④部分Build菜单 RebuildAllStartDebug
第二章从结构到类的演变 struct结构名{可以像CC如果在定义结构时,将数据成员使用private没有使用private定义的成员函数,默认为public。构造函数名对象名(初始化参数 1class代替struct,就是一个标准的类。#includeusingnamespaceclassPoint{ double //类PointPoint(){Point(){Point(doublePoint(doublea,doubleb)voidvoidSetxy(doublea,doubleb)voidvoidDisplay(voidPointPoint
Point的对象PointPointPointaa //显示对象b}类名类名具有的属性x和构造函数PointSetxyDisplayx和 上例中的Point类可以看作直角坐标系操作方法,实际上是如何使用数据x和y,以实现预定功能的函数,这里称为成 C难以到底,特别是在软件规模在三四万行以上时,开发和就十分人们使用的自然语言和计算机能够理解并执行的编程语言之间存在很 C++BB属性Display(Setxy(; 操作可用如下的对象结构图表示A和BADisplay(;Setxy(;,相同的铸造工艺,但铸出的零件用途、使 和使用方法都不一样相同的铸造工艺,但铸出的零件用途、使 和使用方法都不一样 1、使用string实际上stringstrfindstr需要的子串;size成员函数计算并输出str的单词长度;substr成员函数用来返回str字符串中的子串。在程序中可以使用string类定义字符串的对象,这些对象属于类,因此还要使用#includestringstringstringstringstr=’A’; //同理stringstr(’A’); 但可以使引号括起来的单个字符常量初始化,即stringstr=“A”;√ stringstr(“A”);√如果stringstr的内容为“abstr[0]=’a’,str[1]=’b’。例:使用string对象及初始化#include#include#includeusingnamespacestd;voidmain(){stringstringstr1("Weareherestringstr1stringstringstr2="Whereareyou?";stringstr2(stringstr1("Wearehere!"),stringstr2="Wherearecout<<"pleaseinputaword:";cout<<"lenghtcout<<"lenghtofthe"<<str1<<"is"<<str1.size(}W!Wearehere!W?Whereareyou?Pleaseinputaword:goodLengthofthegoodis4.程序中使用了两种方法给string类的两个对象初始化,也可将它们定义在一行中:stringstr1("Wearehere!"),stringstr2="Whereareyou?";stringstr1=str1+“将原来的两个str1=str1+“string常用的stringgetlingetline(cin,InputLline,’\nintistring beginend:copy(str1.begin(),str1.end(str2.begin(①成员函数substr用来返回给定字符串的子串,格式为:string如:stringstr1("Wearehere!");语句中要从对象str1中截取字符串stringnewstrare3C++规定字符串的0a33are3取子串的长度为3。stringstrnew=newstr.substr(2,8);和语句stringstrnew=newstr.substr(2,1);等效,都是截取字符e。②成员函数find用来在主串中检索所需字符串,格式为:intinti表示从str10开始查找are3。如果不给位置参数,默认位置参数为0。③stringgetline从流cin给string类的对象,如:stringggetline(cin,InputLline,’\n’cout<<”yourinput:”<<InputLine<<endl;hereyourinput:Iamhere!例:将格式的日期转换为国际格#include<iostream>#include<string>usingnamespacestd;voidmain(){cout<<"EnterthedateinAmericanformat<<"(例如:December25, //注意逗号后面有一个空stringstring//输入时间:Mayintiinti=Date.find("stringstringintk= stringNewDate=Day+""+Month+"stringDay=Date.substr(i+1,k-i-1); //截取日期赋值给字符串DaystringYear=Date.substr(k+2,4); stringNewDate=Day+""+Month+"cout<<"Originaldate:"<<Date<<endl;cout<<"Converteddate:"<<NewDate<<endl;}EnterthedateinAmericanformat(例如:December252002):May28,2002Originaldate:May28,2002Converteddate:28May3、使用complexC++标准库提供complex类定义复数对象,在程序中包含这个类的头文件为:#include<complex>复数(complexnumber)类需要两个初始值:实部和虚部,complexcomlex<数据类型>对象名(实部值,虚部值如:complex<int>num1(2,3); //定义复数2+3icomplexcomplex<float>complex的realimagcout<<num2.real(cout<<num2.real()<<”,”<<num2.imag(标准库提供的类都是经过抽象,代表了一类对象,例如string类描述的是#includestring #includestring str1=“thisisastring str1str2“thisstr2;//定义cout<<str1<<str2.size(str1str2本操作的成员函数,与string string11.2.6stringfind函数与string本身的find函数有两个stringstr1和str2例:演示string对象#include<iostream>#include<string>#includealgorithm>usingnamespacestd;voidmain(){stringstr1=”weare}ereh!ereheraewwearehere!该例中用str1初始化str2,是为了保证在时str2能有足够的空str1,另外要注意ostream_iteratorchar,string2、stringbegin 面的字符串结束位置。如果begin不等于end,算法首先作用于begin所指元素,并将begin前进一个位置,然后作用于当前的begin所指元素,如此继续前进,直到begin等于end为止,所以它们是元素存在的半开区 在实例中,例如str2值为“wrrheeeea!reverse(str2.begin()+2,str2.begin(8);执行后str2wreeeehrabegin()+2~begin+8是一个半开区间,区间包含的元素不是7个,而是上面阴影中包含的6个,即处于begin()+8位置的元素a上例中的&str1[0]~&str1[12]也是这样的一个半开区间,包含的元素是12个13有了这两个成员函数,就可以用它们表示元素区间,使用string定义的字符串中不用字符’\0’为结束符,而使用char定义的字符串则自动在尾部加例:演示string对象使用成员函数表示空#include<iostream>#include<string>#include<algorithm>#include<functional>usingnamespacestd;voidmain(){stringreverse(str1.begin(),str1.end(reverse(str1.begin(),str1.end( copy(str1.begin(copy(str1.begin(),str1.end(),str2.begin(
sortsort(str1.begin(),str1.end(reverse_copy(str1.begin(reverse_copy(str1.begin(),str1.end(),str2.begin( reverse(str2.begin()+2,str2.begin(reverse(str2.begin()+2,str2.begin(copy(str2.begin(copy(str2.begin()+2,str2.begin(sort(str1.begin(),str1.end(sort(str1.begin(),str1.end(),greater<char>( str1=“wrrheeeeacout<<str1<<””<<str2<<endl; cout<<(*find(str1.begin(),str1.end(),’e’)==’e’)<<”(*find(str1.begin(),str1.end(),’e’)= //输出10,注意上面的find不是成员函数find个数组使用这些操作,swap成员函数可以用来交换两个数组分量。例:演示string#include<iostream>#include<string>#include<algorithm>usingnamespacestd;voidmain(){copy(str[i].begin(),str[i].end(stringstr[]={“wearehere!”,”whereareyou?”,” copy(str[i].begin(),str[i].end( //for循环,换行分别输出wearehere! Whereareyou? e!”str[2]=“wearehere!”//互换,str[0]=“Whereareyou?”str[1]=“ }
//for循环,换行分别输出Where Wearewearehere!Whereareyou?WhereareWearecout<<str[i第三章函数和函数模板C3§3.1一、C++的函数参数传递方CCC#include#include<string>usingnamespacestd;①void用voidvoidmain()stringstr1(“现在”),str2(“过去 //定义对象str1和 //使用传值方式传递函数实参str1和str2数据 cout<<”返回后:str1=”<<str1<<”}voidswap(strings1,string//定义string类的对象s1voidswap(strings1,string{stringstringcout<<”交换为:str1=”<<s1<<”}第二步:执行②语句,发生函数调用,主调函数swap(str1,str2)将实参str1和str2的值分别传递给被调函数swap(s1,s2)的形参s1和s2。程序输出结果:交换为:str1=过去str2=返回后:str1=现在str2=(地址,实参可以是对象的地址值,而不一定非得是指针。虽然参数传递方式仍#include#include<string>usingnamespacestd;voidvoidswap(string*,stringvoidmain()
用stringstr1(“现在”),str2(“过去 //定义对象str1和string //因函数原型中参数的类型是指针,string是完全正确的,即在主调函数中可将对象str1和str2址值&str1&str2 cout<<”返回后:str1=”<<str1<<”}voidswap(string*s1,string//string象指voidswap(string*s1,string{stringstringcout<<”交换为:str1=”<<*s1<<”}程序输出结果:交换为:str1=过去str2=返回后:str1=过去str2=(aaa+1a(aaa+1a素,所以也能采用传地址值的方式,当交换后,因形参的改变,实参也会同时voidswap(int[#include<iostream>usingvoidswap(int[voidmain(intinta[cout<<”返回后:a=”<<a[0]<<”}voidvoidswap(inta[{intinttemp=a[0];a[0]=a[1];cout<<”交换为:a=”a[0]<<”b=”}程序运行结果为:交换为:a=8返回后:a=8四、作为函数参使使 形参对象的地址取实参对象的地址,从而使形参对象和实参对象共享同一个单(例:使用作为函数参数的例子#include#include<string>usingnamespacestd;voidvoidswap(string&,stringvoidmain()
//函数swap,使用string类的对象作为函数形stringstr1(“现在”),str2(“过去 //定义对象str1和 //传递对象的名字str1和 cout<<”返回后:str1=”<<str1<<”}voidswap(string&s1,string//string类的对象s1和s2voidswap(string&s1,string{stringstringcout<<”交换为:str1=”<<s1<<”}交换为:str1=过去str2=现在返回后:str1=过去str2=在程序中调用函数swap时,实参str1和str2分别初始化s1和s2,swaps1s2str1str2s1s2str1str2(系统向形参传递的是实参的地址而不是实参的值,对s1和s2的就是对str1和str2的,所以函数swap改变了main函数中变量str1和str2的值。,“swa(str1str2“swa(&str1&str2#include<iostream>usingnamespacetypedefdoubletypedefdoublevoidavecount(array&b,intvoidavecount(array&b,int }for323,然后执行语1、222值为假;43、4int for(intj=0;j<n-for(intj=0;j<n-if(b[j]<60)}}voidmain(arrayarrayarray}63.64默认参数就是不要求程序员设定该参数,而由编译器在需要时给该参数赋型中说明,默认参数可以多于1个,但必须放在参数序列的后部。例如:intSaveName(char*first,char*second=””,char*third=””,char*fourth=”SaveName时,如不给出参数second、third和fourth,须赋值,如上例中,如果需要给出参数third的值,则必须同时也给first和second赋值。#include<iostream>#include<string>usingnamespacestd;voidvoidDisplay(strings1,strings2=””,strings3=”voidmain(stringstr1(“现在”),str2(“过去”),str3(“未来”); }voidDisplay(strings1,strings2,string{if(s2==””&s3==” elseif(s3””&s2!=”” cout<<s1<<”、
}第一步,执行语句①,函数Display,该函数有三个string类的形参,其中s2s3s2s3序取默认值“”;第二步,执行语句②,定义string类对象str1、str2和str3s1str2str3if条件语句,输出结果“现在”后,返回至语句④Displays1、s2、s3if而不是实参str3s3str1第五步,执行语句⑤,调用语句⑦,将实参str3、str1的值赋给语句⑦中函数Displays1、s2if(而不是实参str3s3str1而不是实参str2s2str3第六步,执行语句⑥,调用语句⑦,将实参str2、str3的值赋给语句⑦中函数Displays1、s2if(而不是实参str2s2str3七、使用const保护数const#include<iostream>#include<string>usingnamespacestd;voidvoidchange(constvoidmain(stringstr(“canyouchange }voidvoidchange(const{stringstring}第一步,执行语句①,函数change使用不允许改变的string类的对第二步,执行语句②,定义string的对象strsstrings2将s+”no!”s2s=s+”no!”sstrings2将s+”no!”s2s=s+”no!”it C++函数的返回值类型可以是除数组和函数以外的任何类型,非void类型的一、返回的函返 的函数原型 方式为数据类型&函数名(参数列表返 的函数原型 方式为数据类型&函数名(参数列表#include<iostream>usingnamespacestd;inta //语句①,定义全局数组int&index(int//语句②,返回的函数index的原int&index(intvoidmain(a[3 a[3}int&index(int //定义返回的函数{returna[i];} 第一步,执行语句①,定义全局数组第二步,执行语句②,函数index返回值
3i,执行语句⑤中的语句,返回a{3(0第四步,执行语句④,输出改后的a[316指针函数:返回值是某种类型数据的内存地址的函数返回指针的函数原型返回指针的函数原型 方式为数据类型*函数名(参数列表例:使用函数inputmain#include<iostream>usingnamespacevoidmain(intfloatfloat
//语句①,返回指针的函数float*//语句②,与inputfloat*for(intfor(intcout<<data[i]<<”cout<<data[i]<<”deletedelete}}
float*input(int&float*input(int& cout<<”Inputnumber:”; if(n<=0return float*buf=newif(buf==0)returnNULL; float*buf=new
for(intfor(intreturnreturn}
第一步,执行语句①,返回值为指针的函数input,该函数使用int型的引第二步,执行语句②,返回值与input函数一样的指针变量input,该函数使用int型的n作为形参,用实参num初始化形参n,n作型的指针变量buf,并分配n个float型数据的空间在n<=0或申请不到空间时退出;执行语句⑦,逐个将输入的buf[i]的值存入已分配的空间中,然后返回指针buf赋给指针data;“data=input(num“data=npu(&umfloat*input(intninput函数时,使用了和该函数返回类型一致的指针变量保存inputinput放由input函数时,使用了和该函数返回类型一致的指针变量保存inputinput放由input返回对象的函数原型返回对象的函数原型 方式为数据类型函数名(参数列表#include<iostream>#include<string>usingnamespacestd;stringstringinput(constvoidmain(){intn;cout<<”Input
//语句①,返回string类的对象的函 //输入要处理的字符串个数stringstring}stringinput(constintstringstringfor(intfor(int
string(均为空串n{cin>>s1;s2=s2+s1+”{cin>>s1;s2=s2+s1+”
return }第一步,执行语句①,返回string类的对象的函数input,该函数使用被const保护的整型数作为形参;第二步,执行语句②,定义整型数n并输入n为空串逐次输入n(string类的对象s2,并将其值赋给string类对象str,然后输出str。InputZhangsanfeng(分三次输入,一次输入一个字符串)Zhangsanfeng#include<iostream>usingnamespaceint //含有两个整型参数的函数原voidmain( coutintmax(intm1,int {return{return(m1>m2? else 使用关键字inline调用此函数的语句出现之前定义,在C++中,除具有循环语句、switch语句例:使用函数isnumber1、不使用内联函数形式时的代码intisnumber(charc){returnintisnumber(charc){returnif(isnumber(ccout<<”你输入了一个数字elseif(isnumber(ccout<<”你输入了一个数字elsecout<<”你输入的不是一个数字}isnumber为提高效率,常将函数main中对函数isnumber的调用替换成表达式,即将mianif(isnumber(cif((c>=’0’&&c<=’9’)?1:0);”,这种替换手工来作很麻烦,可以让C++编译程序来作,方法就是将函数isnumber的定义前面加上关键字inline,变为内联函数的形式即可,这样,C++编译器在遇到对函数isnumber调用的地方都会用这个函数体替换该调用2、使用内联函数形式时的代#includeusingnamespaceinlineinlineintisnumber(charc){returnvoidmain(){…… #include<iostream>usingnamespacedoublemax(double,double);intmax(int,int);charmax(char,char);intmax(int,int,int);voidmain(){cout<<max(2.5,17.54)<<””<<max(56,8)<<”}doublemax(doublem1,doublem2){return(m1>m2)?m1:m2;}intmax(intm1,intm2){return(m1>m2)?m1:m2;}charmax(charm1,charm2){return(m1>m2)?m1:m2;}intmax(intm1,intm2,intm3) intt=max(m1,m2);returnmax(t,m3);}17.5456max(5,9,4)=94(4)个整数的和的程序#include<iostream>usingnamespaceint //两个整数相加的函数intadd2(int,int,int); //三个整数相加的函数add2intadd3(int,int,int,int); //四个整数相加的函数add3voidmain()intadd1(intm1,intm2){returnintadd2(intm1,intm2,intm3){returnintadd3(intm1,intm2,intm3,intm4){returnm1+m2+m3+m4;}#include<iostream>usingnamespacestd;intadd(int,int);intadd(int,int,int);intadd(int,int,int,int);voidmain()intadd(intm1,intm2){returnintadd(intm1,intm2,intm3){returnintadd(intm1,intm2,intm3,intm4){returnm1+m2+m3+m4;}#include<iostream>usingnamespaceintadd(intm1=0,intm2=0,intm3=0,int{returnm1+m2+m3+m4;}voidmain()41add为编译器决定不了是使用形态1、还是形态2的add函数。#include<iostream>usingnamespaceint intadd(intm1=0,intm2=0,intm3=0,int{returnm1+m2+m3+m4;} 2voidmain()intadd(intm1,intm2,intm3){return这段代码在执行到主函数main中语句“cout<<add(1,3,5)”时,因编译器不知道应该重载add函数的哪个形态,将会出错。 C++中规定模板以关键字template和一个形参表开头,形参表中以T#include<iostream>usingnamespacetemplatetemplate<classTmax(Tm1,Tm2){returnvoidmain( //“/t}程序输出结果为:55w2complex#include<iostream>#include<complex>#include<string>usingnamespacevoidprinter(complex<int>
voidvoidprinter(complex<double>voidmain(intcomplex<int>
complex<double> plex初始化complex<double>值}voidprinter(complex<int>{stringstr1(“realis”),str2=”imageiscout<<str1<<a.real()<<’,’<<str2<<a.image(}
voidvoidprinter(complex<double>{stringstr1(“realis”),str2=”imageis”;cout<<str1<<a.real()<<’,’<<str2<<a.image()<<endl;}程序运行结果为:realia2,imageisrealis3.5,imageis32template<classvoidprinter(complextemplate<classvoidprinter(complex<T>{stringstr1(“realis”),str2=”imageiscout<<str1<<a.real()<<’,’<<str2<<a.image(}
语句④,类模板作voidmain(intcomplex<int>
complexcomplex<double> //}第一步,执行语句①,用同名构造函数complex初始化complex对象num1和板执行,输出结果“realia2,imageis3数模板执行,输出结果“realis3.5,imageis4.5虽然2例和3例结果一样但是因3例中complex的参数已经类型参数化,所以程序功能比2例中的函数重载强的多,例如语句“complex<float> printer(num3);”,2例就不能执行,而3例中因参数已经类型同时,就精简函数代码而言,3例中只使用了语句④,便不仅达到而且超过显示比较准则形式为:函数模板名<模板参数>(参数列表2,5)<<endl显示比较准则形式为:函数模板名<模板参数>(参数列表的默认方式:函数模板名(参数列表如语句“cout<<max6.58)<<endlmax(double,int)形式的情况下,语句是无法执行的,这时就要显式的给出比较准则“cout<<max<double6.5,8)<<endl转换,如“cout<<max(6.5,(double)8)<<endl;”,以便正确的由参数列三、关键字typename和使用显式规C++中,关键字typename例:使用关键字typename#include<iostream>usingnamespacetemplatetemplate<typenameTmax(TTmax(Tm1,Tm2){returntemplate<typename
typenameTmin(Tm1,Tm2){return(m1<m2)?m1:m2;} Voidmain(){<<min( //输出 //输出6,6,8 }Tmin<double>(8.5,6“min<int>(2.3,5.8ma<nt>(‘a’’yma<char>(,对参数表中的参数进行强制转换,如“cout<<max(8.5,(double)6“max((int)8.5,6)”,以便程序能够正确的由参数列表推断出模板参数。第四章类和对象 point,pointpoint,它的点位中的任何成员不能使用extern、auto和register关键字修饰、类中的分别称为类的数据成员和成员函数而且不能在类的中对数据成员使用表达1、class类名{来,称为类体,右花括号后的分号作为类的语句的结束标志。均具有一均具有一 和protected来定义,如无关键字,则所有成员默认为private权限(形参列表{成员函数的函数 }ointStxy(int语句表示定义属于PointSetxy,该成员函数带有两个整型形Point{returnGetx(”x;}则Getx为内联函数。赋值是在有了对象AASetxy(25,56不能在类体内或类体外面给数据成员赋值,例如用语句“int同名的构造函数实现的,如在类体中构造函数Point(int,int)后,在主函数中利用构造函数产生对象BPointB(15,25例如对Point类,使用Point在程序中变量,具有Point类的类型的变量称为PointPoint Point类型的对象A和Point*p=&A; //定义指向对象A的Point类型的指针pPoint&R=B; //定义R为Point类型对象B的A.Setxy(25,88; //为对象A赋初值R.Display(; B->Display(; p例:使用内联函数定义Point类及使用Point类指针和#include<iostream>usingnamespacestd;classPoint{ //使用内联函数定义类pointintx,y; voidSetxy(inta,intb)voidMove(inta,intb)
无返回值的内联公有intGetx(){returnx;}intGety(){return
int的内voidprint(Point*a){a->Display();}voidprint(Point&a){a.Display();}voidmain(){Point Point//对象RA为对象APoint
分别以类指针和类作为Ap-setxy重设Bprint//传递指针显示对象Bp->Display(//使用指针调用display函数显示对象BRA.Move(-}如果在上例中的print函数或主函数使用如下语句,将产生错误: xyA①类的成员函数可以直接使用自己类的私有成员(数据成员和成员函数③对象AB当对象的一个函数被调用时,对象执行其的代码来响应这个调用,使对象呈 tt没有再定义一个无参数的构造函数但又了一个没有初始化的对(如Pointvoid①构造函数在类体里的形式类名(形参1,形参2,…形参n; //也可没有形x1、x22:x1(1,x2((1{}a.oint(xya(x,y编译系统会自动调用构造函数Point(x,y)产生对象ax和ya之后,也不能使用a.Point(x,y)改变对象的属性值,而是要设计专门的成员函数如Setxy函数改变对象的属性值。运算符newnew语法以Point类为例,见下面例子。New和构造函数一同起作用,当使用new建立一个动态对象时,new首先分配足以保存Point使用运算符new建立的动态对象只能用运算符delete后,一定要记得使用delete释放空间。例:构造函数的定义、使用过程及运算符new#include<iostream>usingnamespacestd;classPoint{intx,y;Point(Point( {cout<<"InitializingPoint::Point(intPoint::Point(inta,intvoidmain(PointA; //使用不带参数的构造函数产生对象APointB(15,25); //使用带参数的构造函数产生对象BPointPointPointPoint对象数组
Point*ptr1=newPoint*ptr1=newPoint*ptr2=newPoint*ptr2=newdeletedeletedelete //删除动态对象ptr1}InitializingdefaultInitializing15,25InitializingdefaultInitializingdefaultInitializing5,7Initializing8,12InitializingdefaultInitializing5,7#include<iostream>usingnamespacestd;classPoint{intx,y;Point::Point(intPoint::Point(inta,intvoidmain(PointA; //构造函数产生对象APointB(15,25); //构造函数产生对象BPointPoint}Initializing0,0Initializing15,25Initializing0,0Initializing0,0类名&,或不加,为了提高程序的效率和安全性,都必须使用对象 作为形参以Point类为例,构造函数的原型为:Point(oint&; 的定义如下:oint:oint(oint&t){x=t.x;y=t.y;} 、析构函数和构造函数构造函数都是构造型成员函数的基本成员,它的、void如A:~A(void①析构函数在类体里的形式~类名(;:~类名(){}运算符deletedelete删除一个动态对这和使用运算符new建立动态对象的过程刚好相反。例:使用Point#include<iostream>usingnamespacestd;classPoint{intx,y;~ont(~ont(;Point::Point(intPoint::Point(inta,intoint:~oint()voidmain(PointPoint*ptr=newdeletedelete[}Initializing0,0Initializing0,0DestructorisactiveDestructorisdelete调用析构函数时,则按deletenewPoint[22Point为这2delete释放动态对象数组时,用语句delete[]ptr;使运算符delete知道ptr指向的是动态对象数组,deletedelete调用析构函数时,则按delete空的默认析构函数,以Point类为例,默认析构函数形式如下:tt 调用构造函数的综合实#include<iostream>usingnamespaceclassPointPoint(inta=0,intb=0){X=a;Y=b;coutPoint(inta=0,intb=0){X=a;Y=b;coutPoint(constPointPoint(constPointintGetX(intGetX(){returnVoidShow(VoidShow(~Point~Pointcout<<”
&p){X=p.X;Y=p.Y;Cout<<”拷贝初始中中//语句⑤,定义必须使用对象的做形参的构造函voiddisplay(Pointvoiddisplay(Pointp){p.show(voiddisp(Point&p){p.show(voiddisp(Point&p){p.show(Pointfun(Pointfun(){PointA(101,202);returnvoidmain(Point APoint //代码②,定义点类对象B,调用构造函数用A初始化Point //代码③C Cout<<”calleddisp(B)”<<endl; fun(C=fun(
disp(C}
第一,执行代码①,调用语句①,创建点类对象A42、35a、b,a、bAX、Y(在这个构造函数的实现中,它并修改了对象A的私有数据成员X、Y,这是允许的,因为类的成员函数可以直接使用自己类的私有成员,包括数据成员和成员函数第二,执行代码②,调用语句⑤,创建点类对象C,然后将实参A的地址值传递给形参p(采取传的方式时,虽然系统向形参传递的是实参的地址,但实参必须使用对象名,形象的说,就是把实参的名传给了形参p作为A的,p.x和p.Y的值分别赋给点C的私有数据成员X、并输出“拷贝初始化中(在这个构造函数的实现中,它以A的p的形式,了对象A的数据成员A.X和A.Y,并修改了对象C的私有数据X、Y,这是允许的,因为类的成员函数可以直接使用自己类的私有成员,display(BX=,=542,35displaydisp(B35第六,执行代码⑥,先输出“callc=fun(,然后调用语句⑧,调用的过程中先后执行:调用语句①,创建对象AAfun象完成将函数返回值AC,然后调用语句④,析构这个临时对象,输出“删除…101,202101,202disp(C=202out101,20242,35语句④,析构对象A,输出“删除…42,35A(14,25;PointB(A;//用对象A初始化对象B,调用构造函display(B;//对象B作为display()的实参,调用构造函() 不会产生副本从而不需调 构例中:C=fun(; //fun的返回值赋给对象C,调用构造函A(101,202;在其内调用构造函数Point(int,int)创建对象A,然后执行returnA;目的是使C=A,但这个赋值过程需要调用构造函数创建一个临时对象,用这个的函数调用,退出fun()的函数体,此时再调用析构函数析构对象A。 4Max,并在主程序中验证其功能#include<iostream> usingnamespacestd;classMax{ int int//Maxi只允许类的成员函数调int voidSetvoidintMaxiintMaxi A[3intMax::Maxi(intintMax::Maxi(intx,inty)voidvoidMax::Set(intx1,intx2,intx3=0,intx4=0)intintMax::Maxi(){intx=Maxi(a,b);inty=Maxi(c,d);return//Maxix和yMaxi()函数的局部整数对象,如x和y,C++中允许变量便使用便定义。void//为数组对象A[0A[1A[2for(intfor(intcout<<A[i].Maxi(cout<<A[i].Maxi()<<"}程序输出结果为:8976不 类 对象①程序演示了可在类的同时也类的对象,这里是对象数组A,A[3不 类 对象②MaxMaxiMaxi(ini,ini,用Maxi(Maxi(ini,ini后再用这两次的结果作为Maxi(ini,ini)的参数,求出四个数中的最大值。 this数,该参数是一个指向调用该函数的对象的指针,名为this指针,从而使成员使用this指针,保证了每个对象可以拥有自己的数据成员,但处理这些数this指针是C例如当执行A.Setxy(25,55)Setxy(inta,intb)实际oint:Stxy(intb(Point //此时成员函数的this指针指向对象A数(Point*)this,写成下面的形式即可:oint:Stxy(int } 成员。例A、B两个类,可以通过在B类里定义A的对象作为B的数据成员,或者定义一个返回类型为A的函数作为B的成员函数。例:使用Point类的对象及函数作为Rectangle#include<iostream>usingnamespaceclass //定义点类intx,y; voidSet(inta,intb){x=a;y=b;}//语句⑤,定义内联的公有成员函数intGetx(){returnx;} intGety(){return classRectangle{ //定义矩形类RectanglePointLoc; //注释1intH,W; //定义矩形类的高H和宽WvoidSet(intx,inty,inth,intPoint*GetLoc(); //返回Point类指针的成员函数GetLocintGetHeight(){returnH;} intGetWidth(){returnW;} voidRectangle::Set(intx,inty,inth,intw){Loc.Set(x,y);//语句②,注释2Point*Rectangle::GetLoc(){return&Loc;} //注释3voidmain(Rectangle //定义Rectangle类的对象 cout<<rect.GetHeightrect.GetWidth(Point*p=rect.GetLoc(); //语句③,注释4cout<<p->Getx()<<","<<p->Gety()<<endl; //语句④,输出}1PointLocRectangle(如果private利用Point类的对象Loc调用PointSet(x,y并赋值,然后给矩形的高H和宽W注释3:定义返回值类型为Point类指针的RectangleGetLocPoint类对象Loc注释4:定义Point类的指针对象p,并用RectangleGetLoc(Point类对象Loc)第一,类Point,该类具有两个整型私有数据成员x、y;具有一个无返SetGetx第二,类Rectangle,该类具有三个私有数据成员,其中Loc是Point类的对象作为Rectangle类的私有数据成员,H、W为整型数;具有四个公有成员函数其中Set无返回值GetLoc返回值为Point类的指针GetHeight和GetWidth为内联的公有成员函数,返回值为整形数H、W;tange类的公有成员函数StontLoc调用ontt(,y)实现坐标顶点初始化并赋值,然后给矩形的高H和宽W第四,定义Rectangle类的公有成员函数GetLoc,该函数返回值类型为Point类的指针,函数体内语句执行后返回Point类的对象Loc的首地址;RectanglerectRectangle数据成员Loc为PointPointSet2Seta、b的值分别赋给LocLoc的私有数据成员的,此时x、y的值分别变为10、2,Point类的对象Loc(10,2H=h;W=w私有数据成员H、W;第六,执行语句⑧,RectanglerectRectangle员函数GetHeight和Getwidth,输出H、W的值25、20;第七,执行语句③,定义Point类的指针对象p,由Rectangle类的对象rectRectangle类的成员函数GetLocPoint类的对象Loc地址赋给Point类的指针对象p;第八,执行语句④,PointpPoint和Gety,输出Point类的对象Loc的私有数据成员x、y10、2说明:例中Rectangle类具有一个顶点,所以也具有Point类的属性。因RectanglePointPoint类的对象调用Point类的的成员函数来实现对PointPointLocRectangleLocPoint类的成员函数Set(x,y)实现的,语句为Loc.Set(x,y Point A.Setxy(25,55; 2、可以使用对象数组,如语句:Point 定义数组A可以3个Point3、也可以使用指向对象的指针,使用取地址运算符&的地址置于该指针中,如语句:Point* p->Display(; 对象const指针三种方式。以Point函数为例,它们的参数形式分别为:voidvoidprint(Pointvoidvoidvoidvoidprint(Point*p){p- prn(ontprn(ont&prn(ont*对于对象A,print(&A)调用的是原型为print(Point*)的函数形式。3象或对象时,编译系统无法区别这两个函数,重载只能选择其中的一种LocRectangleGetLoc()RectanglePointRectanglerect,rectPointLoc(Loc①类本身的成员函数可以使用类的所有成员(私有和公有成员A.Get(使用A.x。④虽然一个类A可以包含另外一个类B的对象,但类A也只能通过被包含的类BBB的成员函数使用类B如Loc.Set(x,y之前就该类,此时将类作为一个整体来使用,如全局变量指针:class MembersOnly*club; Voidmain(){…函数体} classMembersOnly{…函数体 尽管类的目的是封装代码和数据,它也可以不包括任何,如:classEmpty{};这种空类没有任何行为,但可以产生空类对象。classEmpty{public:Empty(){}},以消只在类中可见,如:classexample{intnum;};inti=num;//定义整型数i,并用num赋值;错误,因为numintnum;//重新定义整型数numnum整型数,与类中说明的数据成员num具有不同的作用域classMyclassintnumber; Myclass的整型数numbervoid Myclass中的标识符intnumber; numberMyclassvoidMyclass:set Myclass中的标识符}Mycass:st(ntMyclassnumber=i;}struct一般不用struct设计类,而是用struct设计只包含数据的结构,然后用这种结 面向对象的早期,主要完善的是面向对象实现(即OOP)阶段,后来(OOD,OOA计1992年OMG(面向对象管理组)制定的面向对象分析和设计的国际标准UML(统模语言)问世后,标记图的方法和技术才真正统一。UMLUML1个含有类名xyxygetx:xyxygetx:floatgety:3AA简C++中的分类结构是指继承(基类/派生类)结构,UML可以动态变化的,称为如下图中Line对象由两个Point另式是用一个类的对象作为一种广义的数据类型来定义整体对象的Lne的颜色和宽度由另外一个嵌套对象LnoorWdth 11对一、一对多和多对多3种连接方式,用一条实线表示连接关系。 这种连接的意义是表明一个教师为某些学生指导要通过消息请求另一个对象为它完成某种服务,则说第1个对象与第2个对象分类(继承)的 :空心菱形表示,如线由两点组 组合(聚合)实例连接:反映静态关系,用实线表 一对象 多对象假设已经定义了类Point,分别使用聚合和继承的方法组成Line类,不涉Pointp1p2Line,Line另外,Line类的数据成员p1和p2需要具有确定的属性值,这由PointLinePointPoint象,消息连接的箭头指向Point 图如用继承的思路构造LineLine类继承Point类的坐标点作为线段因为基类是Point,所以三角形指向Point类,一般情况下,继承关系的消管两者之间有多少消息,也均画出一条,如上图b。称为对象的状态。征,无论对象是简单的或是复杂的,对象一般具有以下特征:⑤对象的操作包括自身操作(施加于自身)求任务的操作。消息传递是系统构成的基本元素,是程序运行的基本处理活动。对象传送的消息一般由对象传送的消息一般由3 一般将类的说明放在头文件中,实现则放在.cpp文件中,主程序单独使用义(即默认内联函数形式,而在.cpp文件中,要将头文件包含进去。嵌入指令#include指示编译器将一个源文件嵌入到该指令所在的位置。尖#includeC++的一部分,因此在这里表示反斜杠时只需使用一个反斜杠如果在C++程序中表示上述文件名则必须使反斜杠如charfname[宏定义的一般形式为:#define宏名替换正文宏定义以#define,#define宏定义的一般形式为:#define宏名替换正文其中宏名必须是一个有效的C#defineMAX(a,b(a)>(b)?\2150宏定义不再使用时,可用#undef条件编译指令是指#if、#else、#elifendifC++的if选择结构,其中#endif表示一条指令结束。其中#ifif开始,到#endif结束,如果#if#else是在#if测试失败的情况下建立另外一种选择可以在#else分支中使用编译指令#error输出出错信息,形式为:#error出错信息 错信息是一个字符序列当遇到#error指令时编译器显示其后面的出错信息,编译指令可嵌套,规则和编译器对其处理的方式与if关键字defined不是指令,而是一个预处理操作符,用于判定一个标识符是否已经被#defined定义,例如标识符identifier已被#defined定义,则义,如果已被定义,则#ifdef为真,#ifndef#ifdefifndef如:#if!defined(HEAD_H)和#ifndefHEAD_H两语句效果一样。Point.h
Point.hclass……//类体
第五章特殊函数和成员 如果在一个类A中说明的数据成员的类型属于另外某个类或某些类,则称这些成员为对象成员。在类A中说明对象成员的一般形式为:class1成员名1;2成员名类名n成员名AA(0AA(012,…,成员(参数表 {……//其他操作“参数表0对象成员构造函数的调用顺序取决于这些对象成员在类A中说明的顺序,与它们在成员初始化列表中的顺序无关。当建立A类的对象时,先调用对象成AA#include<iostream>usingnamespacestd;classobject{intval; //int型的object类的私有数据成员valobjectval(0objectval(0cout<<”信息一object(inti):val(i){object(inti):val(i){cout<<”信息二class
//类object
~objectcout<<~objectcout<<”信息三
object//object类的对象one为container类的对象成员,初objectobjecttwo; //object类的对象two为co
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年公共卫生与预防医学考试试卷及答案解析
- 色浆基体树脂产业分析报告
- 担保借贷合同(16篇)
- 新教师物理课堂互动策略计划
- 科研单位生物安全专职人员职责
- 幼儿园日常运营维护计划
- 海上安全合作困境研究-以中印尼、澳印尼海上安全合作为例
- 因甲方未提供必要条件导致停工的通知范文
- 臭氧熏蒸联合聚乙烯纳米包装处理对双孢蘑菇采后褐变、软化及滋味物质的影响
- 基于NIRS的脑卒中患者运动功能及康复评估研究
- DB61T 5113-2024 建筑施工全钢附着式升降脚手架安全技术规程
- 2025年水工维护(高级工)职业技能理论考试题库(含答案)
- 子宫内膜异位症的综合医疗方案
- 《生物科技》课件
- 城建档案地方立法研究
- 小学音乐课堂教学与劳动教育融合的实践研究
- GB/T 6075.6-2024机械振动在非旋转部件上测量评价机器的振动第6部分:功率大于100 kW的往复式机器
- 教科版2024-2025学年六年级下册科学3.6《浩瀚的宇宙》同步练习(附参考答案)
- 店面装修施工方案范文
- BIM技术在建筑工程造价管理中的应用分析
- 工程签工单表格范本
评论
0/150
提交评论