引言 1
第一部分 预备课程:C语言回顾 7
第一章 C,C的变量、函数和表达式 9
声明简单变量 9
存储分类 10
全局变量 11
局部变量 11
声明函数 12
C的表达式 13
运算符的优先级 14
算术运算符 14
位运算符 15
逻辑运算符 15
赋值运算符 16
杂项运算符 17
关于特殊运算符的考虑 17
结束语 18
第二章 C指针 19
声明和使用简单指针 19
指针的运算 21
指针增量 21
指针的其它运算 22
数组和指针:我们能把它们联系在一起吗? 22
向函数传递指针 23
函数指针 24
堆内存 25
结束语 26
第三章 用户自定义类型:C的结构 27
C结构101 27
C结构指针 28
结构指针的运算 29
使用结构指针 29
结构和函数 30
从堆中分配结构 31
结束语 31
预算程序的C版本:BUDGET1.C 33
25分钟练习 39
第二部分 C++的非面向对象的特征 43
第四章 进入C++ 45
我们是如何到达这里的? 45
最初的年代(1950~1960) 45
函数的年代(1960~1975) 46
结构化的年代(1975~1990) 46
面向对象的年代(1990~现在) 46
为什么C要++? 46
结束语 47
第五章 几个简单的问题 49
新的注解风格 49
为什么需要它? 49
它怎样工作? 49
在任何地方声明变量 50
为什么需要它们? 50
它们怎样工作? 50
常数变量 52
为什么需要它们? 52
它们怎样工作? 52
挥发性变量(Volatile Variables) 54
为什么需要它们? 54
它们怎样工作? 55
引用类型说明符 55
为什么需要它? 56
它怎样工作? 56
结束语 58
第六章 声明函数 59
函数原型 59
为什么需要它们? 60
为什么我喜欢编译器挑我的错? 60
它们怎样工作? 61
内联函数(Inline Functions) 63
为什么需要它们? 63
在C中我做不到吗? 63
它们怎样工作? 64
快了多少? 65
函数重载 66
为什么需要它? 67
它怎样工作? 67
什么可以作为“本质区别”? 68
什么不足以区别重载函数? 68
该做啥就做啥,但是别重组函数名 69
函数的缺省变量 70
为什么需要它们? 71
它们怎样工作? 71
和重载的冲突 71
结束语 72
第七章 I/O流 73
在我有了printf()后,为什么还需要流? 73
关于I/O流的案件:第一部分 73
关于I/O流的案件:第二部分 74
I/O流怎样工作? 74
结束语 76
把预算程序改写为C++程序:BUDGET2.CPP 77
25分钟练习 83
第三部分 类的入门 87
第八章 面向对象的程序设计 89
抽象和微波炉 89
函数方法下的nachos制作 90
面向对象方法下的nachos制作 90
分类和微波炉 91
函数的分类 91
面向对象的分类 91
为什么要分类? 91
面向对象的程序设计和效率 93
结束语 94
第九章 在C++中加入类 95
为什么把类增加到C++中? 96
怎样把“类”加入C++中? 96
命名成员函数 97
在类中定义一个成员函数 98
在类之后保持一个成员函数 99
调用一个成员函数 99
用指针调用成员函数 100
在成员函数中访问成员 101
重载成员函数 102
结束语 103
第十章 保护成员 105
保护成员 105
为什么需要它? 105
它怎样工作? 106
再谈为什么应该使用保护成员? 107
类能够保护它的内部状态 107
通过一个限制接口很容易使用类 108
通过限制接口很容易支持类 108
简单地说友元函数是什么? 111
为什么需要友元函数? 111
它们怎样工作? 111
结束语 113
第十一章 构造函数 115
建立对象 115
构造函数 117
为什么需要它们? 117
它们怎样工作? 118
析构函数 121
为什么需要它? 121
它怎样工作? 121
结束语 123
第十二章 找出类 125
面向对象的分析和设计 125
一个分析问题和设计解决方案的例子 126
快速分析和设计:一种结构化方法 127
快速分析和设计:一种面向对象的方法 127
一个对该问题的面向对象的解决 129
结束语 130
使用类的预算程序:BUDGET3.CPP 131
25分钟练习 137
第四部分 轻松自如地运用类 143
第十三章 制作构造函数的参数 145
带有参数的构造函数 145
为什么需要它? 146
它怎样工作? 146
重载构造函数 148
缺省的缺省构造函数 150
构造类成员 151
构造对象的顺序 155
局部对象有序地进行构造 156
静态对象只被构造一次 156
所有全局对象在main()之前被构造 156
构造全局对象无特殊顺序 157
成员以其被声明的顺序进行构造 158
析构函数以构造函数相反的顺序被调用 158
结束语 159
第十四章 更具有价值的新关键字 161
新关键字:现在你可以不再使用malloc()和free()了 161
为什么需要它们? 161
它们怎样工作? 162
分配数组 162
结束语 164
第十五章 拷贝构造函数 165
拷贝构造函数 165
为什么需要它? 165
它怎样工作? 166
自动拷贝构造函数 167
浅拷贝对比深拷贝 169
对临时对象还有很多要了解的东西 171
结束语 173
第十六章 改变对象的类型 175
无名对象 175
为什么需要它们? 175
它们怎样工作? 176
用构造函数进行类型转换 177
结束语 179
第十七章 静态成员 181
静态数据成员 181
为什么需要它们? 181
它们怎样工作? 182
访问静态数据成员 182
静态数据成员的用途 184
静态成员函数 185
结束语 187
维护一个更合理的预算:BUDGET4.CPP 189
25分钟练习 195
第五部分 继承 199
第十八章 继承 201
为什么需要继承? 201
继承怎样工作? 203
构造子类 204
“有一个”关系 205
结束语 206
第十九章 虚成员函数 207
为什么需要多态性? 209
多态性怎样工作? 210
用多态性方式制作Nacho 211
什么时候虚函数不被多态地重载 213
什么时候定义为“虚”的 215
结束语 216
第二十章 类分解和抽象类 217
分解 217
抽象类 222
它们怎样工作? 223
由一个抽象类制造出一个实在类(honest class) 224
传递抽象类 225
为什么需要纯虚函数? 225
决定实时类型 226
结束语 229
用继承来改造Budget程序:BUDGET5.CPP 231
25分钟练习 237
第六部分 可选的特征 247
第二十一章 多重继承 249
多重继承如何工作? 249
继承的模糊性 250
虚拟继承 251
构造多重继承的对象 255
结束语,一个相反的建议 255
第二十二章 访问控制说明符 257
真正“专有的俱乐部”:私有成员 257
什么时候用private,什么时候用protected? 257
如何使用private? 258
非公共继承 258
什么条件下不是子类? 261
结束语 261
第二十三章 运算符重载 263
为什么需要重载运算符? 263
如何操作一个运算符函数和一个函数? 264
这与重载运算符有什么关系? 265
重载运算符是如何工作的? 265
更详细看一看 266
作为成员函数的运算符 268
重载的另一个麻烦事情 269
转换运算符 271
结束语 272
第二十四章 赋值运算符: 273
为什么重载赋值运算符如此重要? 273
如何重载赋值运算符? 274
结束语 275
第二十五章 I/O流 277
流I/O如何工作? 277
fstream子类 278
strstream子类 281
控制符 281
一般插入运算符 283
灵活的插入运算符 285
结束语 287
第二十六章 对象有效性和标志域 289
用无效指针调用成员函数 289
结果怎么样? 290
如何对待无效指针? 291
isLegal()还能干什么? 293
结束语 293
第七部分 进一步的说明 295
第二十七章 避免在程序中出现错误的十种方法 297
使所有的警告信息和错误信息开关有效 297
使用STRICT编译 298
坚持“干净的”编译 298
采用清晰和一致的编码风格 299
限制可见性 300
使用标志域 301
写代码时给出注释 301
对每条路径至少单步跟踪一次 301
不要重载运算符 302
避免多重继承 302
第二十八章 本书前面未包括的近十个C++特征 303
模板 303
异常处理 304
运行时的类型标识(RTTI) 305
名称空间 305
重载new和delete 305
String类 305
指向成员运算符的指针—>*和. 305
Intel 16位指针 306
第二十九章 十个最重要的编译器开关(附加两个) 307
内联(inline)函数的outline选项 307
定义预处理符号 308
在.obj中包括调试信息 308
检查堆栈溢出 309
存储器模式 309
浮点类型的支持 309
编译器优化 310
使能异常/RTTI处理 311
数据边界对准 311
处理器支持 312
标准堆栈结构 312
预编译头文件 312
附录 虚函数到底是如何工作的? 313
v_table 314
结束语 316
词汇 317