C讲义

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

目录
1.1C++的基本知识.......................................
1.1.1....................................... 命名空间
1.1.
2................................ C++输入输出简介1.2C++对C语言与类无关的性能扩充.......................
1.2.1........................... 新增const常量定义符
1.2.2........................................... 功能
1.2.3........................................... 定义
1.2.4......................... C++中为什么要提供const
1.2.5....... 正确区分const在修饰指针时的两种不同用法
1.2.6....... 正确区分符号名之前有无const修饰时的不同
1.2.7正确区分C语言中的#define与C++中的const的不同:1.3bool类型 ...........................................
1.4string类型 .........................................
1.4.1.......................... 定义string类型的变量
1.4.
2........................... 转换为C风格的字符串
1.4.3................................... s tring的使用1.5枚举类型............................................
1.5.1........................... 枚举类型的声明和定义
1.5.
2................................... 匿名枚举类型1.6变量的块内定义......................................
1.6.1..................... 正确理解C中变量的定义要求
1.6.
2.......................... C++中的变量定义的规则
1.6.3.............. 正确理解C++中的变量的各种作用域。

1.7变量的引用操作符&...................................
1.7.1........................................... 引用
1.7.
2..................................... 定义的语法
1.7.3................................. 引用调用的优点
1.7.4. 正确区分引用在如下两种不同的应用场合时的差别:
1.7.5............. 函数形参定义为引用参数时的调用要求
1.7.6........... 函数形参定义为引用参数时的的编程效果第2章C++对C与类无关的扩展(2)..........................
2.1函数................................................
2.1.1....................................... 函数原型
2.2函数返回一个引用....................................
2.2.1..................................... 引用的返回
2.3内联函数............................................
2.3.1........................................... 含义
2.3.2..................... 为什么内联函数优越于宏替换
2.3.3................................. 内联函数的定义
2.3.4..................... 不适宜定义为内联函数的场合
2.4函数默认参数........................................
2.4.1....................................... 函数重载
2.5函数模板............................................
2.5.1....................................... 函数模板
2.6定义语法............................................
2.6.1....................................... 应用实例
2.7new和delete操作符 ................................. 第3章C++对C语言与类有关的性能扩充.......................
3.1基本知识............................................
3.2面向对象(ObjectOriented)..........................
3.2.1................................ 面向对象(OO):
3.2.2................... 面向对象程序设计方法(OOP):
3.2.3....................................... 应用实例
3.2.
4.................................... O OP的优点:
3.3抽象................................................
3.3.1................................... 如何实现抽象
3.4封装................................................
3.5继承与派生..........................................
3.6多态性..............................................
3.7类和对象............................................
3.7.1.................................... C++中的类:
3.7.2......................... 如何正确定义出类的成员
3.7.3........................... 类中成员的访问控制项
3.8类中成员之间的访问方式:............................ 第4章C++类和对象的编程...................................
4.1对象的含义..........................................
4.2对象定义语法........................................
4.3客观对象............................................
4.4C++中的对象.........................................
4.5使用对象............................................
4.6类中的各种特殊成员函数..............................
4.6.1................................... 内联成员函数
4.6.2....................... 允许带有缺省形参值的函数
4.6.3................................. 类中的函数重载
4.6.4....................................... 构造函数
4.6.
5....................................... 析构函数
4.6.6................................... 拷贝构造函数
4.7异常处理............................................
4.7.1................................. 异常处理的方法
4.7.2................................... 异常规格说明第5章C++中的对象的各种编程...............................
5.1对象赋值............................................
5.1.1........................................... 方法
5.1.2....................................... 应用目的
5.1.3....................................... 实现规则
5.2对象数组............................................
5.2.1..................................... 定义的语法
5.2.2....................................... 访问方法
5.2.3............................... 对象数组的初始化
5.2.4................... 对象数组编程时的构造函数设计
5.2.5................... 对象数组编程时的析构函数设计
5.3对象指针............................................
5.3.1.............................. C/C++语言中的指针
5.3.2................................ C++中的对象指针
5.4对象可以作为函数的形参和返回值的定义................
5.5类中包含有对象成员(类的聚集,对象内嵌,包容法使用类
的资源)................................................
5.6类中的静态成员......................................
5.6.1................................. 静态成员的编程
5.6.2........................... 静态成员的访问方法:
5.6.3....... 静态成员函数与非静态成员函数之间的访问:
5.7C++中的this指针.................................... 第6章友员函数与运算符重载................................
6.1友员函数............................................
6.1.1....................................... 友员函数
6.1.2........................... 为什么需要友员函数:
6.1.3........... 友员函数与成员函数在编程方面的不同点
6.1.4友员函数与一般函数(非成员函数)在编程方面的不同点
6.2友员类:............................................
6.2.1........................................... 含义
6.2.2................................... 友员类的定义
6.2.3....................................... 应用目的
6.3类的引用性前向说明..................................
6.4运算符重载..........................................
6.4.1............................... 运算符重载的实现
6.4.2....................... 使用类的成员函数实现重载
6.4.3........................... 使用友员函数实现重载
6.4.4................................... 自动类型转换
6.4.5..................... 运算符重载编程的进一步说明第7章C++类的继承与派生...................................
7.1入门知识............................................
7.1.1继承...........................................
7.1.2派生...........................................
7.1.3为什么需要继承与派生...........................
7.1.4应用的目的.....................................
7.1.5继承的可行性...................................
7.2如何实现继承与派生..................................
7.2.1................................... 基类和派生类
7.2.2............................... 派生类的定义语法
7.2.3............................. 如何设计派生类成员
7.3继承的方式..........................................
7.3.1............................. 三种继承的方式差别
7.3.2................. public和private继承方式的区别
7.4继承的多重性........................................
7.4.1含义...........................................
7.4.2对象的多重相关性...............................
7.4.3多重继承时的派生类的定义语法...................
7.4.4应用场合.......................................
7.5继承时的构造函数....................................
7.5.1....................................... 设计原则
7.5.2定义的格式.....................................
7.6继承时的析构函数....................................
7.6.1....................................... 设计原则
7.6.2....................................... 定义格式
7.6.3........................................... 原因
7.6.4....................................... 调用次序第8章多重多级继承及虚基类................................
8.1多重多级继承时访问二义性............................
8.1.1................................. 访问时的二义性
8.1.2........................... 在多重继承时的二义性
8.1.3........................... 同名支配(覆盖)原则
8.1.4........................... 在多级继承时的二义性
8.2虚基类..............................................
8.2.1....................................... 定义语法
8.2.2........................................... 作用
8.2.3..................... 如何判断是否为虚基类的问题
8.2.4..................................... 处理的方法
8.2.5............. 带有虚基类的最远的派生类的构造函数
第9章多态性和虚函数......................................
9.1多态性..............................................
9.1.1......................................... 多态性
9.1.2........................................... 作用
9.1.3................................... 赋值兼容原则
9.1.4..................... 指向派生类及基类对象的指针
9.2虚函数..............................................
9.2.1....................................... 定义语法
9.2.2................................... 虚函数的特点
9.2.3............................... 为什么需要虚函数
9.2.4....................................... 静态联编
9.2.5................................. 动态联编的应用
9.2.6............................... 如何实现动态联编
9.3虚析构函数..........................................
9.3.1........................................... 原因
9.3.2....................................... 应用场合
9.4纯虚函数和抽象基类..................................
9.4.1....................................... 纯虚函数
9.4.2....................................... 定义语法
9.4.3............................. 抽象基类的编程规则
9.4.4................................. 抽象基类的用途第10章综合应用............................................
10.1类模板..............................................
10.1.1.................................... 模板的声明10.1.2.................................... 模板的使用
第1章C++对C与类无关的扩展(1)
【本章中的知识要点】
□正确理解C语言与C++语言的差别
□C++对C语言扩充体现的几个方面
【重点难点】
□const用法
□string用法
□引用
1.1C++的基本知识
1.1.1命名空间
C++提供名字空间来防止命名的冲突。

例如,如果两个库都定义了cout,当一个应用程序使用这两个库时,将导致命名冲突。

大型应用系统由许多人来完成,命名冲突是一种潜在的危险,程序员必须细心的定义标志符以保证名字的唯一性。

名字空间std涵盖了标准C++的定义和声明,例如:std::cout。

❑命名空间的声明:
namespacettl
{
intx;
}
❑命名空间的使用(两种方式):
1)先引用再访问例如:
usingttl::x;或者usingnamespacettl;
x=6;x=6;
2)直接访问如:
ttl::x=34;
1.1.2C++输入输出简介
C++的基本输出包括cin和cout。

1.2C++对C语言与类无关的性能扩充
1.2.1新增const常量定义符
1.2.2功能
它用来冻结一个变量的值,使其值在程序中不能被进一步改变(置成只读属性,即变为常量)。

1.2.3定义
const类型定义符变量名==初值;
如:constintsumValue=10;//常量定义
constint*ptr;//限定指针
voidFunction(constint&X)//限定函数的形参
{
}
1.2.4C++中为什么要提供const
其目的是替代C语言中的编译预处理命令#define(常量定义),但比它更加语义精确
因为#define无法准确地反映常量的数据类型。

如:
#definesumValue10//此时的sumValue是char型还是int型?
对变量一经const修饰后,必须给它赋初值(但用于函数的形参时不需赋初值),一经const修饰后便不能修改此符号名之值。

❑constintx=12;
x=54;//error
❑voidDisplay(constint*ptr,constintn)
{
cout<<ptr[0];//==*(ptr+0),显示数组中的第一个元素之值
ptr[0]=1; //错误,不能修改其值(不能通过指针来改变目标单元之值)
*ptr=1;//错误,不能修改其值(不能通过指针来改变目标单元之值)
}
1.2.5正确区分const在修饰指针时的两种不同用法
❑constint*ptr=&X;此时不能通过指针来访问改变目标单元之值,即*ptr=1是错误的,但是ptr本身可以被改变ptr=&Y;
此种用法常见于函数的形参。

voidfun(constint*ptr)
{*ptr=1;//错误的
}
❑int*constptr=&X;此时ptr本身不可以被改变(ptr=&Y是错误的);但ptr所指向的目标的单元之值是可以被改变的(如*ptr=2;即X=2);此时ptr类似于数组名(常量指针)。

intptr[10];
ptr[0]=2;
1.2.6正确区分符号名之前有无const修饰时的不同
❑intsum=1;//无const修饰时
此时sum为变量,意味着其值可以被改变(如:sum=2;);
同时其内存字节数为两个字节(在PC下为16位)。

❑constintsum=1;//有const修饰时
此时sum为常量,意味着其值不可以被改变(如:sum=2;);
同时不需要占用内存空间。

另外C++语言视经const修饰的
符号名为常量特性,因而它可以用于任何可能出现数字常量
的场合(如数组的大小的说明等)。

constintArraySize=10;
chararray[ArraySize];
1.2.7正确区分C语言中的#define与C++中的const的不同:❑由#define所定义的符号名为全局性常量,因而在整个程序中应保持符号名的唯一性;
❑const可以说明一个局部或全局性同名常量(据此可以改变const符号名之值)。

❑另外在语法方面,#define为编译预处理命令,而const为定义符,语句以“;”结束。

#defineMin1
constintMax=100;
voidmain(void)
{#defineMin2//错误,不能再定义同名常量
constintMax=200;//可以再定义同名局部常量
}
要点✍const也可以限定引用与函数(见后文介绍)。

1.3b ool类型
在C语言中真值用非零表示,假值用零表示。

C++新增了数据类型bool(增加可读性),可以取值true或false,用来表示真值或假值。

bool依然支持非零和零的形式。

例如:
intval;
cin>>val;
if(val)

也是合法的。

如果val的值非零,条件判断为真(true);如果val 的值为零,条件判断为假(false)。

在默认情况下,bool表达式输出时,真值为1,假值为0。

例如:boolflag;
flag=(3<5);
cout<<flag<<’\n’;
的输出为:
1
可以用以下方式使其输出结果为true:
cout<<boolalpha<<flag<<’\n’;
1.4s tring类型
C++提供string类型来代替C语言的以null为结尾的char类型数组。

使用string类型必须包含头文件string。

有了string类型,程序员不用需要关心存储的分配,也无需处理繁杂的null结束字符,这些操作将由系统自动处理。

1.4.1定义string类型的变量
方式如下:
strings1;
strings2="Hello";
strings3=s2;
strings4("HelloWorld");
1.4.2转换为C风格的字符串
我们经常会在程序设计中遇到需要C风格字符串的情况(如以null结尾的char数组)。

例如,当我们打开一个文件,而文件又要求必须为一个C风格字符串时,则可用函数c_str如:
stringfilename=”tt.txt”;
ifstreamif;
if.open(filename.c_str());
1.4.3string的使用
【实例练习】
#include<iostream>
#include<string>
usingnamespacestd;
voidmain()
{
stringstr="Hello";
cout<<"str="<<str<<"str长度为:"<<str.length()<<endl;
strings(10,'*');//s表示含有十个'*'的字符串
cout<<s<<endl;
stringstr1;
cout<<"请输入一个字符串:";
cin>>str1;//注意:输入的字符串以空格或回车代表输入结束cout<<"str1="<<str1<<endl;
strings1="Hello",s2="File";
strings3=s1+s2;
cout<<"s3="<<s3<<endl;
if(s1==s2)
cout<<"s1=s2"<<endl;
else
cout<<"s1!=s2"<<endl;
}
1.5枚举类型
1.5.1枚举类型的声明和定义
在C语言中,我们如下方式声明一个枚举类型:
enumCOLOR{RED,GREEN,BLUE};
然后可以定义一个类型为enumCOLOR枚举类型变量:
enum COLORCL;
而在C++中可以不用关键字enum,如下:
COLORCL;
1.5.2匿名枚举类型
声明形式:enum{MAX=1000,MIN=1};
在这里我们可以将MAX和MIN作为常量使用,例如,
intarr[MAX];实际上enum的主要用途就是定义常量。

1.6变量的块内定义
1.6.1正确理解C中变量的定义要求
一般应该集中定义出。

例如在C中:
voidmain()
{intx=1;//正确
for(inti=0;i<10;i++)//错误
{inty=2;
printf(“%d”,y);
intc=10;//错误。

}
}
1.6.2C++中的变量定义的规则
可以采用“随用随定义”的方式定义出变量,即变量的块内定义---C++中允许变量在使用之前的任一语句块中定义出来,包括for循环中。

voidmain(void)voidmain(void)
{intx=1;//局部变量{for(intloop=1;loop<10;
loop++)
{inty;//块内变量{intz=1;//块内变量
x=3,y=4;}
}}
}
1.6.3正确理解C++中的变量的各种作用域。

❑文件域----全局变量(其作用域为从定义点到当前文件结束有效)。

❑函数域-----局部变量(其作用域为本函数内有效)。

❑函数原型域-----函数的形参,为局部变量,只在该函数体内有效。

❑块内域-----块内定义的变量(比局部变量的作用域更小),块内定义的变量的作用域为从定义点到当前块内有效,语句块执行完毕,自动释放。

【实例练习】
intX=1;//全局变量
voidFunction(inta)//函数的形参
{intb=a;//局部变量
X=b;//正确
Y=X;//错误
}
voidmain()
{intY=2;//局部变量
X=2;//正确
Function(X);
for(inti=0;i<10;i++)//块内定义的变量
{X=2;//正确
intC=0;//块内定义的变量
}
X=2,Y=3;//正确
C=X;//错误
}
1.7变量的引用操作符&
1.7.1引用
C++利用“&”来产生一个变量的引用(该变量的别名,同一内存单元二种不同的变量名)。

intX=1;
int&NewX=X;
NewX=3;//注意:改变的其实为变量X
printf("%d",X);//X的值被改变为3,因为X与NewX其实为同一
个变量。

1.7.2定义的语法
❑类型定义符&变量名=原变量名;
如:intsumValue=1;
int&sumData=sumValue;
即sumData与sumValue为同一个变量,但在不同的应用场
合下以不同的变量名出现。

❑为什么要提供引用操作符:C++中的引用主要是用来解决函数调用中形参为指针型的参数时编程其函数体时的不安全性(易
出错),操作更加简单、安全。

如:intadd(int*X,int*Y)改进为intadd(int&X,int&Y)
{*X=*X+*Y; {X=X+Y;
return*X; returnX;
} }
voidmain()voidmain()
{inta=1,b=2;{inta=1,b=2;
add(&a,&b);add(a,b);
}}
【蓝梦提示】
□在这两种情况下,调用时都是采用传地址方式调用,但采用引用调用时编程其函数体时较简单、安全。

1.7.3引用调用的优点
通过引用调用可以提高调用速度,因为只需要传送地址而不需要直接将大量数据拷贝,因而特别适用于形参为大量数据的应用场合。

如:
structData
{inta[1000];
}AData;
voidfun(structDataX)
{
}
这是采用传值调用时的函数定义,但是在调用时的效率较低,因为需要进行实参与形参之间的数据拷贝
voidfun(structData&X)
{
}
这是采用引用调用时的函数定义,在调用时的效率较高,因为形参与实参之间本身是同一个变量。

从而在调用fun(AData)时,如果使用二种不同函数定义时,其调用效果不同。

选学内容✍有关函数调用的两种型式----传值调用与传地址调用
❑传值调用:当函数的形参是以“值”的形式定义时,系统将以传值拷贝方式被调用,在调用时实参拷贝到形参,但在内存中将同时存在实参和形参,调用时占用两倍的内存空间,同时调用时的效率较低。

voidadd(intx,inty)
{returnx+y;
}
voidmain()
{inta=1,b=2;
add(a,b);//在调用时刻在内存中
同时存在a,b与x,y变量。

}
❑传地址调用:当函数的形参是以“地址”的形式定义时,它将以传地址方式被调用,在调用时系统将实参的地址传送到形参中,但在内存中将仅有一份参数存在(此时实参和形参变为同一变量),调用时的效率较高。

voidadd(int*x,int*y)voidadd(int&x,int&y)
{//C语言的编程方法{//C++
语言的编程方法
return*x+*y;
returnx+y;
} }
voidmain()voidmain()
{inta=1,b=2;{inta=1,b=2;
add(&a,&b);add(a,b);
}}
1.7.4正确区分引用在如下两种不同的应用场合时的差别:
❑对一般的变量进行引用:如引用的变量不是用作函数的形参或返回值,则说明时必需加以初始化以指明它的同地址变量。

voidmain(void)
{intX=3;
int&refX=X;
fun(refX);
cout<<X;//X的值被改变为4
}
voidfun(int&a)
{a++;//a为refX的引用
}
函数的形参为引用:如引用的变量用作函数的形参或返回值,则说明时不必要加以初始化以指明它的同地址变量,此时形参为实参的引用。

intadd(int&X,int&Y)//正确intadd(int&X=1,int&Y=2)//错误
{{
X=X+Y;X=X+Y;
returnX;returnX;
}}
1.7.5函数形参定义为引用参数时的调用要求
调用时实参不能为常量而必须为赋已知值的变量。

因为编译器无法为常量(无内存地址)建立内存地址,从而无法产生引用。

同时在函数调用时系统将实参地址拷贝到形参,从而使形参即为实参,但在函数体内采用形参名来访问它。

intadd(int&a,int&b)voidmain()
{{intX=1,Y=2;
returna+b;add(X,Y);//调用正确
}add(1,2);}//调用错误
1.7.6函数形参定义为引用参数时的的编程效果
❑其一能在一个函数体内访问或修改另一个函数体内定义的变量的值。

【实例练习】
#include<iostream>
usingnamespacestd;
voidIncValue(int&X);//函数的原型说明或定义(在C++中必须强制说明)
voidmain()
{intA=1;
IncValue(A);
cout<<"TheValueofAIs:"<<A<<endl;//注意C++中的标准输出与C中的不同
}
voidIncValue(int&X)
{X=X+1;//表面上为改变X的值,其实是改变了main()内的A的值
}
❑其二是能使某一函数间接实现“多个返回值”(因为在正常情况下,函数只能实现返回一个值)。

【实例练习】
#include<iostream>
usingnamespacestd;
voidCalculateCircle(intR,float&CircleLen,float&
CircleArea);
voidmain()
{intcircleR=10;
floatLength,Area;//定义时未赋值
CalculateCircle(circleR,Length,Area);
cout<<”CircleLength=”<<Length;//经调用后它们被赋值
cout<<”CircleArea=”<<Area;
}
voidCalculateCircle(intR,float&CircleLen,float&CircleArea)
{CircleArea=3.1415*R*R;//CircleArea引出到Area
CircleLen=2*3.1415*R;//CircleLen引出到Length
}
【蓝梦提示】
□C++语言中的函数在调用时不仅可以引入参数(利用形参),而且也能引出参数(单个参数时采用return语句,而多个参数时采用形参为引用定义的方
式)。

【本章总结】
本章主要讲解了C++的基本输入输出、命名空间的应用
以及const、string、bool类型的应用引用的基本用法。

第2章C++对C与类无关的扩展(2)
【本章中的知识要点】
□函数原型及带默认形参的函数
□返回引用的函数
□内联函数、函数重载、函数模板
□操作符new和delete用法
【重点难点】
□函数重载及函数模板的应用
2.1函数
2.1.1函数原型
在C语言或C++语言中,我们使用术语“定义“来表示一条变量分配存储的语句,或表示函数头和函数体。

我们使用术语“声明”来表示对某个数据类型的描述。

函数原型体现了函数声明的风格,它指的是函数头以及函数头中包含的参数列表。

例如:intf(intx,inty);
便是对函数f的声明。

在C++中没有参数的函数参数表可以为空,但在C 中要有一个void参数如:
intdisp(){函数体;}//C++写法
intdisp(void){函数体;}//C语言写法
2.2函数返回一个引用
2.2.1引用的返回
C++中,默认情况下,当函数返回一个值时:
return expression;
expression被求值,并将该值拷贝到临时存储空间,以便函数调用者访问。

我们将这总返回方式称为传值返回。

当调用如下函数:
intf(){returni;}
时,i的值将拷贝到临时存储空间,调用者是i的一个副本,也就是说如果调用函数f:
j=f();
则i的值就拷贝到临时存储空间,然后在拷贝到j,(见图1-5)
临时存储空间
i拷贝到拷贝到j
8 ======
=> 8 ==
=====>
8
图1-5传值返回
函数返回值还有另外一种形式,即引用返回。

在这种情况下返回值不再拷贝到临时存储空间,甚至连return语句所用的那个存储单元对调用者都是可访问的。

引用返回语法是在返回类型前加一个&标记。

int&f(){returni;}此时再次调用f时即j=f();i的值直接拷贝到j中(图1-6)。

i拷贝到j
8 =====
=>
8
图1-6
注意:如果有这样的函数定义:
int&f()
{
inti;
returni;//error:
}
是错误的,当f返回时i已经不存在了。

2.3内联函数
2.3.1含义
内联函数类似于宏扩展。

当预处理器扩展一个宏时,它将用宏定义替换每个宏。

当宏替换或函数扩展完成后,再执行程序,这样避免了函数调用的开销,程序可以更有效的执行。

使用宏或内联函数的缺点是,如果函数很大或很多地方都调用了这个函数,程序的可执行码变得很大。

2.3.2为什么内联函数优越于宏替换
与通过预处理器进行宏阔展不一样,内联函数的扩展是通过编译器完成的。

当预处理器扩展一个宏时,它只是进行简单的文本替换,而不考虑代码的语义。

而编译器扩展内联函数时,就不得不考虑语义了,正因为这个原因,内联函数通常比宏更受欢迎。

2.3.3内联函数的定义
【实例练习】
#include<iostream>
usingnamespacestd;
inlinevoidswap(int&,int&);//函数声明
intmain()
{
intI=7,j=-3;
swap(I,j);
cout<<”I=”<<I<<endl
<<”j=”<<j<<endl;
return0;
}
voidswap(int&a,int&b)
{
intt;
t=a;
a=b;
b=t;
}
注意关键字inlilne出现在函数声明而不是函数定义部分。

2.3.4不适宜定义为内联函数的场合
如果函数体内有循环语句、条件语句、switch等控制流语句时,不能定义为内联函数,因为它们有改变程序流程的语句,系统无法正确地进行宏替换
2.4函数默认参数
C++允许程序员在函数声明中以常数形式为函数指定默认值。

如果在调用函数时不提供这个参数,则将使用默认值代替。

voidf(intx,inty=5,intk=6);//函数声明
对函数的有效调用方式是:
f(12,32,123);
f(12,32);
f(23);
这里要特别注意函数的声明顺序。

例如:
f(intx,inty=5,intz);//错误
f(intx,inty=12,intz=34);//ok
f(intx=23,inty=3,intz);//错误
函数参数初始化的顺序是从右向左一次进行的。

2.4.1函数重载
C++允许在同一范围内使用相同名字的函数,但要保证函数参数个数或参数类型不同。

如果有多个明为f的函数被定义,就称f被重载。

编译器通过实参类型与同名函数的参数表进行匹配以决定调用哪个函数。

例如:
voidf(intx,inty);
voidf(intx);
voidf(floatx,floaty);

f(12,12);//调用f(intx,inty)
f(13);//调用f(intx)
f(12.12f,12.432f);//调用f(floatx,floaty)
2.5函数模板
2.5.1函数模板
它是C++中实现静态多态性的一种手段,可以用来创建一个通用功能的函数以支持多种不同形参,进一步简化重载函数的函
数体设计(因为有些重载函数的函数体是相同的)。

intadd(intx,inty)
{x=x+y; //函数体是相同的只是不同类型的形参
returnx;
}
floatadd(floatx,floaty)
{x=x+y;//函数体是相同的只是不同类型的形参,为什么不可以只写一个呢?
returnx;
}
2.6定义语法
使用关键字template来定义说明一个函数模板
template<classType>//或者template<typenameType>
Typeadd(TypeX,TypeY)
{returnX+Y;
}
要点 采用Type来代替某一数据类型定义符(占位符号),告诉编译器此处可以用合适的数据类型替代。

2.6.1应用实例
求各种类型的两数之和
【实例练习】
#include<iostream>
usingnamespacestd;
template<classType>
Typeadd(TypeX,TypeY)//定义两
数之和函数模板
{returnX+Y;
}
template<classType>//定义三数之和函数模板,但第二个数必须为整数
Typeadd(TypeX,intY,TypeZ)
{returnX+Y+Z;
}
template<classType>//定义三数之和的函数模板,但第二个数必须为浮点数
floatadd(TypeX,floatY,TypeZ)
{floatf=X+Y+Z;
returnf;
}
voidmain(void)
{
cout<<add(1,2)<<'\n';
cout<<add('!','#')<<'\n';
cout<<add(1.2,3.4)<<'\n';
cout<<add(1,2,3)<<'\n';
cout<<add(1,2.3f,4)<<'\n';
}
【蓝梦提示】
□在函数模板调用时必须保证实参与形参相互匹配。

2.7n ew和delete操作符
含义:new和delete用于动态分配和释放存储空间。

用法:new和delete必须配套使用,由new开辟的空间一定要由delete 来释放。

例如:
int*p=newint;//new进行动态分配的时候会返回它所开辟的内存的地址

deletep;//当不再使用p时,一定要对它进行释放;
也可以象这样来创建:
int*p=newint(5);
//动态分配一个整型空间并将其初始化为5
也可以用new动态分配一个连续的存储空间,例如:
int*p=newint[5];//动态分配5个整型空间

delete[]p;
【本章总结】
熟练掌握函数重载及函数模板的应用。

第3章C++对C语言与类有关的性能扩充
【本章中的知识要点】
□面向对象程序设计方法及编程思想
□OOP的四个基本机制(抽象、封装、继承、多态)
□C++的源程序格式。

【重点难点】
□面向对象的特点及如何实现对事务的抽象。

3.1基本知识
1、OOP(ObjectOrientedProgramming)是面向对象程序设计方法,是
目前程序设计的主流方法。

2、C++是混合编程语言:C++是在C的基础上产生又保持与C相兼容,
因而C++既可以实现面向对象编程又可以实现面向过程编程(兼容C)。

3.2面向对象(ObjectOriented)
3.2.1面向对象(OO):
它是一种解决问题的方法或者观点,它认为自然界是由一组彼此相
关并能相互通信的实体(Object ,中文为“对象”)所组成的。

如“人

类”的相互关系如下:
兄朋友


3.2.2面向对象程序设计方法(OOP):
❑含义:它要求程序员使用面向对象的观点来分析问题(即将所要解决的问题转化为程序中的对象---任何问题在程序中都被映射为对象),以找出问题的属性(通过数据来描述)与方法(通过函数来体现),然后用计算机语言来描述,最后在计算机中加以处理的一种程序设计方法。

❑编程要求:程序员在描述或处理问题时应具有高度的概括、分类并对它加以抽象的能力,才能准确地描述出某一实体(待解决的问题)。

❑应用目的:实现软件设计的产业化,变手工作坊式编程为软件构件式工业化,达到快速高效编程。

实现可重用的软件组件。

❑编程特点:
①根据所要解决的问题的各个相关性转化为程序中的各个
类相关性,然后将每个类具体化产生出对应的问题对象,以消息传递的机制来组织对象之间的相互作用。

②程序组成形式---对象+消息,对象与对象之间通过消息作
为连接相互驱动。

对象(问题)之间的关系是编程关心的重点,而对象(问题)的功能实现过程则处于次要的地位(只在某一函数内考虑问题的实现)。

3.2.3应用实例
计算两数之和
✍设计流程:
❑定义出一个“加”类---描述出各种类型的数相加操作;
❑将此类(实例化)具体化以定义产生出一个对象(代表本次计算的问题);
❑向此对象发送一条消息----将二数相加并发送消息参数;
❑再向此对象发送一条消息----显示出总和值。

【实例练习】
#include<iostream>
usingnamespacestd;
classAddClass //定义一个"加"类
{
public:
voidAdd(intx,inty) {
sum=x+y;
}
voidAdd(floatx,floaty){
sumf=x+y;
}
voidprintSum(intflag){
cout<<"TotalSum="<<sum;
}
voidprintSum(floatflag){
cout<<"TotalSum="<<sumf;
}
private:
intsum;
floatsumf;
};
voidmain(void){
AddClassaddObj;//定义出一个对象(它代表所要解决的问题"1+2=?")
addObj.Add(1,2);//向此问题的对象发送一条"累加"的消息同时附带二个消息参数
addObj.Add(3.4F,5.6F);
addObj.printSum(1);//再向此问题的对象发送一条"显示总和"的消息
addObj.printSum(1.0F);
}
3.2.4OOP的优点:
❑实现数据与方法的封装,通过方法来操作改变数据,提高了数据访问的安全性;
❑程序更加模块化,便于代码重用;
❑由于程序是类的集合从而可以根据问题的相关性来组装程序,而面向过程则是函数的集合,零零散散不便于代码重用。

3.3抽象
对具体问题(对象)进行分类概括,提取出这一类对象的公同性
质并且加以描述的过程。

编程的要求:
❑先注意问题的本质及描述,其次是实现过程或细节。

它直接决定程序的优劣----类的定义及组成元素;
❑所涉及到的主要内容:数据抽象(属性)---描述某类对象的属性或状态(对象相互区别的物理量),代码抽象(方法)---
描述某类对象的共有的行为特征或具有的功能。

3.3.1如何实现抽象
通过类的定义这一机制来达到。

实例1✍钟表这一类对象
❑数据抽象
------intHour,intMinute,intSecond
❑代码抽象------SetTime()、ShowTime()
实例2✍人这一类对象(人类----地球上的
所有人)
❑数据抽象
------char*name,char*sex,intage
❑代码抽象------Eat()、Work()、Walk()、
Study()
【蓝梦提示】
□对同一类问题可以有不同的抽象结果,这取决于程序员看问题时的视角3.4封装
提供将抽象出的数据成员、代码成员相组合的一种机制,它能将这二类成员再组合在一起,形成问题的类,然后再根据类来实例化以产生对象(或实体)。

相关文档
最新文档