C++语言讲义Word文档格式.docx
《C++语言讲义Word文档格式.docx》由会员分享,可在线阅读,更多相关《C++语言讲义Word文档格式.docx(120页珍藏版)》请在冰豆网上搜索。
一、类的概述
二、类与对象的关系
三、类的声明、类的构成
四、类声明和成员函数定义的分离
35
五、类中的运算符重载
36
六、数据类型转换与显式构造函数
37
七、继承与派生
40
八、多态性与虚函数
42
第四单元string与输入输出流类
46
一、C++中的字符串string
49
二、C++中的标准输入输出流类
第五单元C++标准模板库
58
一、类模板或模板类
二、STL概述
三、序列式容器——元素排列次序和置入时次序一致
60
四、仿函数(Functionobjects,Functors)
65
五、关联式容器
67
六、其它容器
68
七、算法概述
70
八、算法纵览
74
九、关于算法的一个综合示例——多叉路口交通灯的管理问题
76
十、STL迭代器
81
十一、标准异常
85
附录一致计算机系05级全体同学的一封信
89
附录二一个表达式分析器源码
90
附录三我的第一个MFC练习程序
91
一、为什么要学习C++?
从多个方面来思考这个问题
Ø
计算机软件最多的是由何种语言写成的?
计算机工业、教育和科研领域最多的是使用何种语言来进行交流的?
运行效率最高的
功能最强大的
学习资料最丰富的
——C++己成为全世界专业编程人员的首选语言
摘自《标准C++宝典》
——C语言是程序员的语言。
使人吃惊的是,并不是所有的计算机编程语言都是为程序员设计的。
摘自《C++:
TheCompleteReference》
——C++是一个难学易用的语言。
——C++的难学,不仅在于其广博的语法、语法背后的语义、语义背后的深层思维、深层思维背后的对象模型;
C++的难学,还在于它提供了四种不同但却相辅相成的编程思维模型:
……。
在如此庞大复杂的机制下,万千使用者前仆后继的动力是:
一旦学成,妙用无穷。
摘自《MoreEffectiveC++》
——虽然只商业化不到10年,C++却俨然成为几乎所有主要计算环境的系统程序语言霸主。
——C++拥有比语言更丰富的东西。
是的,C++还有一个伟大的标准程序库。
总之,要成为一个真正的程序员,必须学习C++,因为在只有学习过C++之后,才真正拥有进行各种软件开发的能力,不论是网络应用软件、数据库操作软件、数据库管理系统、操作系统还是各种开发环境、各种语言的编译器和解释器。
当然,在学过C++之后,如果我们只是专门从事某一个方面的工作的话,通过学习那些专门为这一方面而设计的语言来加快开发的进程是可取的。
但要记住,C++是你必须跨过的门槛。
二、怎样学习C++
(关于学习C++之我见)
C++的学习一般分为三个阶段
1.C++语言的学习。
2.运行库和STL(StandardTemplateLibrary标准模板库)的学习。
3.在Windows或Unix环境的程序设计中学习运用各种类库。
时间上的分配
第一阶段(C++语言的学习)一到二个月
第二阶段(运行库和STL)三个月
第三阶段(Windows或Unix程序设计)六个月
第一阶段的学习用书
《标准C++宝典》(林丽闽译)
《ThinkinginC++》(C++编程思想)(第一卷)
《C++Primer》
《TheC++Completereference》(C++参考大全)
《TheC++ProgrammingLanguage》(BjarneStroustrup)
第二阶段的学习用书
《C++标准程序库》(侯捷译)
《ThinkinginC++》(第2卷)
第三阶段的学习用书
《ProgrammingWindowswithMFC》
《DesktopApplicationswithMicrosoftVisualC++6.0》
《深入浅出MFC》
《ProgrammingVisualC++》
《ProgrammingWindows》
C++讲义
无忌此时不过九岁,虽然聪明,但要短期内领悟谢逊这些世上罕有的武功,却怎生能够?
谢逊又教他转换穴道、冲解穴道之术,这是武学中极高深的功夫,无忌连穴道也认不明白,内功全无根柢,又如何学得会了?
谢逊便又打又骂,丝毫不予姑息。
殷素素常见到儿子身上青一块、乌一块,甚是怜惜,向谢逊道:
“大哥,你武功盖世,三年五载之内,无忌如何能练得成?
这荒岛岁月无尽,不妨慢慢教他。
”谢逊道:
“我又不是教他练,是教他尽数记在心中。
”殷素素奇道:
“你不教无忌武功么?
“哼,一招一式的练下去,怎来得及?
我只是要他记着,牢牢的记在心头。
”
……张无忌此时自己明白了义父的苦心,义父一身武功博大精深,倘若循序渐进的传授拆解,便教上二十年也未必教得完,眼见相聚时日无多,只有教他牢牢记住一切上乘武术的要诀,日后自行体会领悟。
——《倚天屠龙记》
一、C/C++语言标准
1)C语言由DennisRitche发明,1989年成为ANSI标准(C89),1999年提出新的C标准(C99)。
2)C++语言由BjarneStroustrup于1979年提出并完善,1998年成为ANSI/ISO标准。
3)《TheDesignandEvolutionofC++》一书详细介绍了C++的发展历程。
4)期待中的C++0X。
二、C++与C的不同
1)C++是面向对象的程序设计语言,C是面向过程的。
2)头文件的不同。
(<
string.h>
VS<
string>
)
3)注释的不同。
(//)
4)局部变量声明的位置不同。
(任何位置VS只有开头)
5)增加了新的关键字。
6)C++引入了函数模板和类模板,支持泛型编程。
(《泛型编程与STL》)
7)C++引入了运行时类型识别RTTI。
8)C++引入了新的异常处理机制。
9)C++中的new和delete代替了C中的malloc和free。
10)C++引入了名空间机制来避免名称冲突。
11)C++中函数名若不带参数可以不声明void。
12)运行库有了大的变动。
13)C++标准中包含了STL。
可以说,C++标准的发布对C++领域带来了翻天覆地的大变动——不是来自语言本身,而是来自标准程序库。
—《LearningStandardC++asaNewLanguage》
三、如何在VC中编译C/C++源程序
1)在VC中编译的方法为:
选择File/New,在New向导的Projects选单中选择Win32ConsoleApplication,同时在Projectname中给工程取名,并在Location中为工程选定工程保存目录,然后选择OK。
2)在Win32ConsoleApplication-step1of1对话框中选择Anemptyproject,然后选择Finish,并在NewprojectInformation对话框中选择OK。
(这样我们就新建了一个新的、控制台应用程序的工程,工程尚未包含任何程序文档。
下面我们将用两种方法将源程序加入到工程中去。
3)第一种方法
a)用一种文本编辑器编辑C/C++源程序。
b)将编辑好的源程序保存为cpp文件或h文件。
c)在VC中选择Project/AddtoProject/Files,在InsertFilesintoProject对话框中指定要加入到工程中的一个或多个文件。
4)第二种方法
a)在VC中选择Project/AddtoProject/New,New向导的Files选单中选择C/C++HeaderFile或C++SourceFile,并勾选AddtoProject,同时为文件取好名字,然后选择OK。
b)然后在工程的工作区的文件视窗中选择并打开刚才加入的空文件,在其中输入源程序即可。
5)最后,请在VC中编译并运行源程序。
a)当编译时出现错误时,可将光标放在错误号的前面然后使用F1键来查询相应错误所产生的原因。
b)当需要查询某些函数的定义时也可使用F1键来完成。
注:
使用两种方法编译例1-01。
四、内联函数
1)目的:
提高效率
使用macro也可提高效率,但有缺陷。
a)macro看上去像函数调用但却并非总是像函数那样行为,因而可能隐藏许多难以发现的bug。
b)macro无法访问类对象的成员。
2)使用:
短小代码、频繁使用的代码可以声明为内联函数。
3)内联函数中不能有循环语句。
4)只是C++标准对C++编译器实现的一个建议。
5)Anyfunctiondefinedwithinaclassbodyisautomaticallyinline.
6)方法:
函数前加上inline即可。
五、函数重载与安全链接
1)C++中允许多个函数共用同一函数名,只要它们之间的参数个数或参数类型或参数顺序有所区别即可。
2)函数重载与二义性
有时编译器不能在重载函数之间作出选择称具有二义性的重载。
//例1-02
#include<
iostream>
usingnamespacestd;
floatmyfunc(floati){returni;
}
doublemyfunc(doublei){returni;
intmain()
{
cout<
<
myfunc(10.1);
//OK,无二义性
myfunc(10);
//二义性
return0;
原因一:
C++的自动类型转换。
例如:
编译此例并查看错误号,说明错误号的命名规则,如何查看帮助
floatmyfunc(floati,intj=1){returni+j;
原因二:
在重载函数中使用默认变元。
3)函数重载引起的链接问题
a)如果在不同的转换单元中声明了多个同名函数,C++链接器如何确定将链接的函数体呢?
为解决这个问题,C++采用了名字重组(namemangling)技术,给编译器内部的函数标识符重新命名。
重组后的函数名包括了指定函数返回值类型和参数类型的标志。
在可重定位的目标文件里,对函数的调用以及函数的定义都被转换成重组后的名字,而这个名字里惟一的。
b)
#ifdef_cplusplus
extern“c”{
#endif
……
C++可以重组函数,其它语言则没有此功能(例如C),为了使得在C++中也能调用己编译的C函数,必须通知C++链接器和编译器停用函数名重组技术,这时使用extern“C”{……}的链接说明——声明大括号内的内容都是用C编译器编译的。
六、引用
1)引用是个别名,必须初始化,不能为空,不可改变其值,实现机制与指针相似,最常用于函数形参。
2)向函数传递参数可有值传递、指针传递和引用三种方法,对于大型结构,值传递效率低下。
3)如果指向的变量可能不存在就使用指针,若确信变量肯定存在就用引用。
4)
voidmyFunc(double*pd)
if(pd){cout<
*pd;
}
如果使用指针就要测试是否为NULL。
七、关于new与delete运算符
1)C++程序的内存格局分为四个区
①全局数局区②代码区③栈区④堆区
全局变量、静态数据和常量放在全局数据区;
所有函数以及类的成员函数的代码放在代码区;
为运行函数而分配的局部变量、函数参数(返回数据、返回地址)存放在栈区。
以上三区的内存一经分配不得变动。
2)很多情况下需要从堆中动态分配内存(如动态链表中结点的插入与删除)(凡是要根据输入才能确定需要创建对象的种类和数量的情况)
3)在堆中分配了内存,一定要在不需要时释放——内存泄漏将减少可用系统资源,严重的导致内存不足而死机。
4)当要释放的是指向数组的指针时使用delete[]。
八、其它
1)续行符\
2)pascal与cdecl
int_pascalmyfunc(int,int);
int_cdeclmyfunc(int,int);
因为C与pascal的参数入栈次序不同(C是从右至左)
参看MSDN中程序员指南中的CompilerErrorC2560。
3)argument与parameter
argument——实参(函数的调用者提供给函数的参数)
parameter——形参(函数定义中的参数)
4)关于函数的返回
a)exit——不但终止正在被调用的函数,也结束了整个程序。
b)return——从当前被调用的函数返回上层函数
c)自动返回——运行到程序的最后。
九、练习(关于优先级与结合性)
1)char*(*(*var)())[10];
var是一个变量
var是一个指针变量
var是一个指向函数的指针
var所指函数的返回值是一个指针
这个返回的指针指向一个数组
这个数组是一个字符指针型数组
2)unsignedint*(*const*name[5][10])(void);
name数组是有50个元素的二维数组
数组中的元素是一个个的常量指针
这些指针分别指向一个指向函数的指针
这些函数的返回值为无符号整型指针
说明时参考MSDN\VisualC++Programmer'
sGuide\LanguageQuickReference\ReferenceTables\OperatorPrecedenceandAssociativity。
忠告:
学习C++一定不要拘泥于语法(不是说不要遵循语法),即不要刻意去背诵记忆语法,因为所有的语法参考在编写程序时可以很快地参考到,并且语法的错误也是很容易被编译器所发现的。
ThepreprocessorperformspreliminaryoperationsonCandC++filesbeforetheyarepassedtothecompiler.Thepreprocessorallowsyouto:
1.Defineandundefinemacros.
2.Expandmacros.
3.Conditionallycompilecode.
4.Insertspecifiedfiles.
5.Specifycompile-timeerrormessages.
6.Applymachine-specificrulestospecifiedsectionsofcode.
——摘自MSDN
预处理指令是以#号开头的代码行。
二、编译指示指令#pragma编译指示
如:
#pragmaonce指示该文件每次编译时只被包含一次
参考MSDN中VisualC++Programmer'
sGuide/PreprocessorReference/PragmaDirectives
三、
//例2-01
#defineError(n)std:
:
”Error”#n
intmain()
Error(53);
#号运算符出现在宏定义中的#运算符将跟在其后的参数转换成一个字符串,有时将#称为字符串化运算符。
如例2-01:
宏展开成std:
”Error”#”53”
相邻字符串被合并成std:
”Error53”
sGuide/PreprocessorReference/PreprocessorOperators
四、
//例2-02
#definejoint(b,c,v)b##c##v
unsignedbcv=joint(5,12,43);
std:
bcv;
##号运算符—用于将参数连接到一起。
如例2-02
五、函数模板/模板函数
1.第一部分是模板标识符与模板参数列表template<
typename/classT>
第二部分则声明函数原型,此时可以使用模板参数列表中的参数来声明函数的返回值了。
2.如果在重载函数时,一个是非模板的同名函数,一个是同名的模板函数,编译器会优先使用非模板的重载同名函数。
3.必须保证函数模板实参的类型能通过函数的编译。
//例2-03
template<
typenameT>
Tmax(Ta,Tb,Tc)
if(b>
a)a=b;
if(c>
a)a=c;
returna;
strings1,s2,s3,s4;
s1="
123"
;
s2="
234"
s3="
345"
s4=max(s1,s2,s3);
s4<
endl;
一般类不能作为比较对象的,除非重载了<
和>
运算符,如果没有重载的话,将不能进行编译。
如例2-03:
能否通过编译呢?
为什么?
六、VC程序设计初步
1)你可以调用的函数有哪些?
C语言程序:
CRuntime函数库(运行时库)
win32API
C++语言程序:
MFC
STL
2)这些函数的来源
CRuntime函数库
⏹LIBC.LIB——CRuntime函数库的静态链接版本
⏹MSVCRT.LIB——CRuntime函数库的动态链接版本的入口函数库
MFC——MFCXX.DLL(既可动态链接也可静态链接)
Win32API——GDI32.DLL、USER32.DLL、KERNEL32.DLL以及COMMDLG.DLL、MAPI.DLL等。
请到windows系统中找到这些文件的所在目录。
如可以在C:
\ProgramFiles\MicrosoftVisualStudio\VC98\Lib目录下找到MSVCRT.LIB、COMMDLG.LIB和LIBC.LIB。
又如可在C:
\ProgramFiles\MicrosoftVisualStudio\VC98\MFC\Lib下找到MFC42.LIB,可以在C:
\WINDOWS\system32(winXP)中找到MFC42.DLL。
3)VC程序设计应当了解的内容
C运行时库中有哪些函数?
STL中有哪些内容?
用法与用途?
MFC中有哪些类?
各有何作用?
win32API有哪些?
4)关于这些内容的帮助在哪里——熟记MSDN的内容分布
MSDNLibrary/Visualstudio6.0Document/VisualC++Document/
⏹usingVisualC++/VisualC++programmer′sGuide/
◆LanguageQuickReference
◆Run-TimeLibraryReference
◆BuildError
⏹Reference/
◆MFC参考
◆输入输出流类参考
◆STL参考
◆C++语法详细参考
MSDNLibrary/platformSDKDocument/——所有win32API的参考
⏹baseservices
⏹userinterfaceservice
⏹win32API
5)获取帮助的方法
查找MSDN(使用F1键)
查找并阅读源程序。
(使用VC中的FindinFiles——在多个文件中查找指定字符串)
6)一个综合的例子:
例2-04(一个使用了MFC、STL和win32API的例子)
a)在VC中选择File/New,在New对话框中的projects选单中选择Win32ConsoleApplication,再选择projectname为Test,选择好工程位置(可任意,如D:
\temp)。
b)在Win32ConsoleApplication-step1of1对话框中选择AnapplicationthatsupportsMFC,再选择Finish/OK。
c)将test.cpp中_tmain函数中的
CStringstrHello;
strHello.LoadString(IDS_HELLO);
(LPCTSTR)StrHello<
去掉。
d)在test..cpp文件的头部、在#include“stdafx.h”之后加入#include<
fstream>
。
e)
CStringfilename,extoffile;
CFileDialogdlgFile(TRUE);
if(dlgFile.DoModal()==IDOK)
{filename=dlgFile.GetPathName();
extoffile=dlgFile.GetFileExt();
MessageBox(NULL,"
你选择的文件