首页 > 代码库 > C++ 编程思想(第一卷)阅读总结

C++ 编程思想(第一卷)阅读总结

最近工作闲翻阅了之前买f《C++编程思想》这里贴上我认为对我最有帮助的部分,一来留给自己复习看,另一方面也和小伙伴们分享下:

1 OPP相关

1.1、每个对象都有一个类型,OOP中class 和type是同义词,在面向对象的程序设计中,我们所做的工作实际上就是创造新的数据类型,程序员定义class 是为了与具体问题相适应,而不是被迫适用已存在的数据类型。

1.2、当用<>来指定文件时,预处理器以特定的方式来寻找文件,一般是环境中或者编译器命令指定的某种寻找路径;当采用""指定文件时,通常是从当前目录开始寻找,如果文件没有找到则按<>方式进行寻找。

2 C++总的C

2.1、整数类型范围从小到大为:short int->int->long int。

         浮点类型范围从小到大为:float->double->long double;

         unsigned 数不保存符号,因此有一个多余的位可用,所以它能存储比signed数大两倍整数

2.2、main()的内部和外部定义的变量存放在不同的区域;数据和函数也存在不同区域

2.3、C++编程的一般原则是在定义时进行初始化,const 变量必须有初始值

2.4、enum可以提高程序清晰度,采用union可以节省内存,所有union 变量地址都是一样的

2.5、 采用预处理器来完成代码调试功能,具体实现如下:

#define NDEBUG 
//......
#ifdef NDEBUG
/* debugging code here*/
......
#endif
2.6、C++允许将任何类型的指针赋给void* ,但是不允许将void* z指针赋值给其他任何类型的指针。

2.7、同文件是我们和库用户之间的合约,合约描述了库中的数据结构,为函数调用规定了参数和返回值,头文件中只限于申明,为了避免头文件的内容的多次申明,我们可以采用如下方式避免:

#ifndef HEADER_FLAG
#define HEADER_FLAG
//Type declaration here
.....
#endif
同样为了避免命名空间的错乱,头文件中绝不会看到using

2.8、如果程序员想允许显式让不属于当前结果的一个成员函数访问当前结构的对象时,可以借助friend 修饰符,friend 必须在一个结构内部声明

3 、C++特色:

3.1、class与struct 的区别在于class的成员默认是private,而struct的成员默认是public;

3.2、C++的安全性体现在初始化和清除两个方面,用构造函数确保初始化,用析构函数确保清除

3.3、C++中宏被内联函数(inline function)代替,这样既保证了高效性(成员函数和预处理器宏一样高效)也保证了安全性(当调用内联函数时,编译器首先确保调用正确,即所有的参数类型都满足,宏定义在预处理中,不能进行检查)。

任何在类中定义的函数都自动的成为内联函数;

使用内联函数的目的是减少函数调用的开心,但是如果函数交大,由于需要在调用函数的每一处重复赋值代码,这样会使得代码膨胀,因此小函数作为内联函数比较理想

3.4、static使得变量存于静态数据区中,而不是堆栈中。全局静态对象的构造函数在main()之前调用,并且在退出main()后调用析构函数;

3.5、 关键字namespace如何class、struct、enum和union一样把它们的成员的名字放到不同的空间去,但namespace与class 、struct、union和enum有着明显的区别:

        (1)namespace只能在全局范围内定义,但他们之间可以相互嵌套;

        (2)namespace定义的结尾不必跟着分号;

(3)一个namespace可以在多个头文件中用一个标识符来定义;

(4)不能像class一样去创建一个名字的实例;

(5)namespace可以用另一个名字作为他的别名;

3.6、 & 在C++表示引用,引用可以理解为一个奇特的指针,这个指针的优点是不必怀疑它是否初始化,引用的使用规则如下:

(1)应用创建是必须初始化;

(2)一个引用指向一个对象后不可转变为另一个对象的引用;

(3)不能NULL的引用

最经常看见引用的地方是函数参数和返回值中,当引用被用作函数参数是,在函数内任何对引用对象的修改将在函数外参数发生变化,当然也可传递指针来做相同的事情,但引用具有更清晰的语法。

3.7、拷贝构造函数(copy-constructor)是一种特殊的构造函数,需要引用来实现从现有的相同类型的对象中产生新的对象。编译器使用拷贝构造函数通过值传递的方式在函数中传递和返回对象

3.8、使用delete void * 可能会出错,在删除之前必须把它转为适当的类型,否则将会丢失内存;

3.9、C++确保在进入新类的构造函数体之前调用酥油的其他的构造函数,这样所有子对象的成员函数所做的任何调用总是转到这个被初始化的对象中,

MyType::MyType(int i):Bar(i){///....}

4 C++ 中的多态

4.1、多态永远发生在派生类中与基类之间,C++通过virtual函数和晚绑定(late binding)实现;

如果一个函数在基类中被申明为virtual ,那么所有的派生类中它都是virtual,可以对基类中的虚函数进行重写;

在每个带有虚函数的类中,编译器秘密放置了一个指针(vpointer)指向该对象的VTABLE(编译器对每个包含虚函数的类创建一个表:VTABLE)

技术分享
编译器从Instrument指针开始,该指针指向该对象的起始地址,对于所有的Instrument或派生对象,他们的vptr都存在相同的位置(常常在对象的开头),所以编译器能够取出该对象的vptr,vptr指向vtable的起始地址,所有的vtable都有相同的顺序,如图。play()第一个,what()第2个;

5、C++模板(template)

5.1、template告诉编译器,随后定义将错做一个或者多个未指明的类型,当这个模板产生实际类代码时,必须指定这些类型使得编译器可以替换他们。



C++ 编程思想(第一卷)阅读总结