<<Thinking in C++ 中文版.pdf >>下载地址:点击打开链接
_________________________________________________________________________________
第一章 对象的演化
1.1 基本概念
类描述了一组具有 相同特性(数据元素) 和 相同行为(函数) 的对象。
通过 “消息” (或 “请求” ) 操作 对象(或“实例”)。
继承表示了 基本类型 和 派生类型 之间的关系
创建一个 基本类型,描述一些对象的思想核心。
多态(晚绑定),当给对象发消息时,在程序运行之前不去确定被调用的代码。
每个对象根据一个 指针 有不同的行为。新添加类型不影响以前的代码。
virtual函数(虚函数)表示允许在相同家族中的类有不同的行为。
对象发现-》对象装配-》系统构造-》系统扩充-》对象重用
1)让特殊问题生成一个类,然后在解决其他问题时,让这个类生长和成熟。
2)尽量保持类的简单,易懂。
第二章 数据抽象
库就是某些人写好的代码,按某种方式包装在一起。
最小的包: 扩展名如LIB的文件 和 向编译器声明库中有什么的头文件。
2.1 声明 和 定义
声明:向计算机介绍自己的名字。
定义:为这个名字分配内存空间。
如果只是声明变量,而不定义它,则使用关键字 extern。
int A;//即是声明,又是定义。
函数,声明可以省略extern关键字。不带函数体 的函数,连同参数列表和返回值 自动作为函数声明。
函数原型,包括关于 参数类型 和 返回值 的全部信息。
在函数声明时,参数名可省略。
库问题之一,我们必须向用户强调 初始化 和 清除函数 的重要性。
库问题之二,声明函数。因为编译器会假设以int作为参数调用的函数包含int参数表。
每个独立的C文件,就是一个处理单元。
在C中,引用就是函数名。
编译器在找出这个名字的全局版本之前,先在局部结构中搜索。
第三章 隐藏的实现
3.6 句柄类
编译器必须知道一个对象的所有部分的声明,以便创建和管理它。
把一个编好的实际结构(类成员变量的声明)放在实现文件中,而不是暴露在头文件中(将类A的成员变量,放入一个新的类B中,在类A的实现文件中声明类B的结构(即类A的结构),类B的指针声明为A成员变量,达到隐藏类A结构的效果)。
以下是文件:Common.h
#ifndef TEST_COMMON_2017_1_22_17_56_FJH_H_
#define TEST_COMMON_2017_1_22_17_56_FJH_H_
//! 句柄类,隐藏类CTestA数据结构到类CTestB. 避免修改数据结构,带来的全部文件重编译
class CTestA
{
struct CTestB;
CTestB *m_pCTestB;
public:
CTestA();
~CTestA();
public:
void InitCtestB();
void FreeTestB();
void ChangeTestB(int nB);
int ReadTestB();
};
#endif //TEST_COMMON_2017_1_22_17_56_FJH_H_
以下是文件:Common.cpp
#include "stdafx.h"
#include "Common.h"
struct CTestA::CTestB
{
public:
int m_nTestData;
};
void CTestA::InitCtestB()
{
m_pCTestB = new CTestB;
if (m_pCTestB == NULL)
{
return;
}
m_pCTestB->m_nTestData = 0;
}
void CTestA::FreeTestB()
{
delete m_pCTestB;
}
void CTestA::ChangeTestB(int nD)
{
m_pCTestB->m_nTestData = nD;
}
int CTestA::ReadTestB()
{
return m_pCTestB->m_nTestData;
}
CTestA::CTestA()
{}
CTestA::~CTestA()
{
FreeTestB();
}
第四章 初始化 与 清除
4.1 用 构造函数 确保初始化
构造函数 由编译器自动调用,确保被执行。可以设置参数,没有返回值。 在C++中,定义 和 初始化 是统一概念,不能只取其中之一。
4.2 用 析构函数 确保清除
析构函数 不带任何参数。当对象超出它定义的范围(包括该对象的 右括号,使用goto语句等),由编译器自动调用。使用对象需要注意: 1)修改了某些硬件条件,需要还原; 2)在屏幕上显示了一些字符,需要清除; 3)在堆中申请了内存,需要释放。 需要注意:如果使用的goto语句是 标准C语言库中的 setjmp 和 longjmp 函数,将不引发析构函数的调用。
4.3 清除 定义块
变量的定义 紧靠着 变量的使用 时,程序可读性更强。
C++要保证一个对象产生时,它同时被初始化。
同时定义和初始化一个变量。
将一个较大的函数细化,由多个小函数实现块功能。
变量在定义之前,总是无法得到存储空间。
内存分配 是通过编译器移动堆栈指针实现。
4.6 集合 初始化
集合:多个事物聚集在一起。
struct Test
{
int m_nA;
float m_fB;
Test(int nA)
{
m_nA = nA;
}
};
Test tArray[] = {Test(1), Test(2), Test(3)}; //正确
//Test tArray1[] = {{1, 1.2}, {2, 2.2}, {3, 3.3}}; //错误,因为定义过构造函数,就必须调用对应的构造函数完成初始化
struct Test1
{
int m_nA;
float m_fB;
};
Test1 tArray1[] = {{1, 1.2}, {2, 2.2}, {3, 3.3}};//正确,没有定义过构造函数
struct Test
{
int m_nA;
float m_fB;
Test(int nA)
{
m_nA = nA;
}
};
Test tArray[] = {Test(1), Test(2), Test(3)}; //正确
//Test tArray1[] = {{1, 1.2}, {2, 2.2}, {3, 3.3}}; //错误,因为定义过构造函数,就必须调用对应的构造函数完成初始化
struct Test1
{
int m_nA;
float m_fB;
};
Test1 tArray1[] = {{1, 1.2}, {2, 2.2}, {3, 3.3}};//正确,没有定义过构造函数
4.7 缺省构造函数
缺省构造函数 不带任何参数的构造函数。 一旦有了一个构造函数,编译器就会确保构造函数会被调用。 在C++中,没有缺省的构造函数,容易引发错误。
第五章 函数重载 与 缺省参数
函数:就是一个操作,命名规范目的是与读者便于交流。 重载:一次多义,从上下文理解它的含义。 函数重载本质:允许函数重名。
5.1 范围分解
所有函数在使用前,必须先声明。
5.2 重载
如果函数之间的行为差异比较大,就不适合用缺省参数。
只有参数列表的后部参数才是可缺省的。
函数参数列表中如果出现一个缺省参数A,那么排在A后的其他参数也必须是缺省的。
缺省参数只能用在函数声明中(编译器必须在使用该函数之前知道缺省参数值),声明一般放在.h文件中。
如下:
float Func(int nT, int fD = 16, float fT = 5.8);//在.h文件中 float Func(int nT, int fD, float fT)//在.cpp文件中 { return nT + fD + fT; }