当前位置: 首页 > Linux

EffectiveC++阅读笔记(一)

时间:2023-04-06 06:02:34 Linux

写在前面:之前一直在写博客,但是没有坚持。感觉博客作为记录自己学习过程的工具还是很有意义的,所以决定在这里开始我的博客之路的第一步,从C++的学习开始,从EffectiveC++开始,收获颇多点赞,记录学习和思考一些问题的心路历程。EffectiveC++给出了55条改进C++程序的具体建议,并提出了一些在C++编程中经常出现的陷阱。建议01:将C++视为一个语言集将C++视为一个语言联盟早期的C++只是C的面向对象扩展。今天,C++已经是一种多范式编程语言。它支持:过程(procedural)面向对象(object-oriented)函数形式(functional)泛型形式(generic)元编程形式(metaprogramming)由4个子集组成,书中称之为“子语言”(sublanguage),我觉得这个描述不太好,尤其是泛型编程和STL,称它为语言总是有点牵强,我更愿意理解为子集的概念,这4个子集分别是:C,C是C++的基础,所以C++完全兼容C语言。当然在一些关键字和结构上还是有区别的,比如C++的static关键字的含义比较复杂。比如struct,c++展开结构类型等面向对象的特性等等,还有一些,但主要区别在于扩展性,这在c中不可用。Object-Oriented,这部分涉及到C++的语言特性,包括面向对象的内容:类(constructor,destructor),封装(encapsulation),继承(inheritance),多态(polymorphism),虚函数(dynamicbinding),etc...这些是OO在C++中的具体实现。模板C++。C++的泛型编程部分是C++的函数模板和类模板,使泛型编程成为STL成为可能。STL是C++的标准模板库(StandardTemplateLibrary),它实现了一系列常见的容器(containers)、迭代器(itrators)、算法(algorithms)、函数对象(functionobjects)。高效的设计模式将它们联系在一起,程序员可以通过使用STL更快地开发出高效的程序。所以我们不能简单的说C++被认为是一种语言,而是要时刻关注它的四个部分的不同规律,并利用它们来完成更好的设计。建议02:尽量使用const,enum,inline代替#definePreferconsts,enums,andinlineto#defines简单修饰,减少简单函数的栈开销,经常使用#define来声明宏变量或宏函数,但是在C++,这是不提倡的,因为#define定义的宏是在预编译阶段展开的,不会在符号表(symboltable)中生成它所描述的变量。同时,如果用宏来描述浮点常量,预编译处理器可能会盲目替换代码中对应的浮点宏变量,虽然这不需要为它分配内存,但实际上代码存储也需要内存,但得不偿失。另外需要注意类中const参数的初始化。一般来说,常量值是在头文件中使用声明式声明的。可以在声明的时候初始化:classGamePlayer{private:staticconstintNumTurms=5;//为了让常量只有一个实体...}或者在类中声明,初始化structGamePlayer{private:staticconstintNumTurms;//声明性头文件(.h)声明...}constintGamePlayer::Numturms=5;//实现文件初始化(cpp/cc)一个有趣的操作是emum补偿,编译器必须在编译时获取数组的大小,有些编译器不允许“staticintclass”常量”完成“int类初始化操作””,也就是不能用类中的staticint常量作为数组的大小。这时候可以用曲线救国,使用所谓的“theenumhack”补偿方式是基于枚举类型的值可以用作int的理论,因此数组可以这样声明:5intscores[Numturms];//declarearray}enumhack有很多用处,了解它很有必要。enumhack的行为类似于#define而不是const,也就是说它没有实体内存,它只是作为一个替换函数,所以它的地址是不能取的,这从某种角度也实现了一种约束。指针不能指向它。根据不同的编译器,有的编译器会为const对象设置额外的存储空间(不带指针和引用),有的编译器会,但是使用enumhack可以保证这部分不会有额外的开销。enumhack仍然是模板元编程(templatemetaprogramming)的基础技术。在什么情况下替换对于简单常量,最好用const对象或枚举替换#define对于类似于函数的宏(macros),最好用内联函数替换#define,虽然编译器会可选内联,但这就是我们想要的。