Effective C++读书笔记(1)

  写在前面:以前一直有在写博客,可是老是没坚持下来,感受博客做为记录本身学习过程的工具仍是十分有意义的,故而决定在这儿开始我博客之路的第一步,以C++的学习为始,从获得大量好评的Effective C++ 开始入手,记录本身学习的路程和对一些问题的思考。c++

effective C++给出了55个改善C++程序的具体建议,而且提出了一些在C++程序设计中常常出现的坑。程序员

建议 01 : 视C++为一个语言集算法

View C++ as a federation of languages

  早期的C++只是简单的在C上作了面向对象的拓展,发展到今天,C++已是一个多重泛型编程语言(multiparadigm programming),它支持:编程

  • 过程形式(procedural)
  • 面向对象形式(object-oriented)
  • 函数形式(functional)
  • 泛型形式(generic)
  • 元编程形式(metaprogramming)

  它由4个子集组成,在书中将其称为"次语言"(sublanguage), 我以为这个描述不太好,特别是对于其中的泛型编程和STL来讲,称为语言老是有些牵强, 我更愿意将它理解为子集的概念, 这4个子集分别为:设计模式

  • C,C是C++的基础,因此C++是彻底兼容C语言的,固然,有部分的关键字和结构仍是有一些区别的,如static关键字C++有了更为复杂的含义。如struct,c++拓展告终构体类型的面向对象特性,等等还有一些其余的,可是主要是拓展性的区别。简而言之,C++就是提供了更为高可用的高效编程,如模板(templates)、异常(exception)、重载(overload)等等,这些在c里面都是没有的。
  • Object-Oriented,这部分就是C++的语言特性相关,包括面向对象的内容: classes(构造函数、析构函数)、封装(encapsulation)、继承(inheritance)、多态(polymorphism)、virtual函数(dynamic binding)、等等...这些就是OO的在C++上的具体实现。
  • Template C++。C++的泛型编程(generic programming)部分,就是C++的函数模板(function template)、类模板(classes template),它们使得泛型编程成为可能
  • STL。STL是C++的标准模板库(Standard Template Library),它实现了一系列通用的容器(containers)、迭代器(itrators)、算法(algorithms)、以及函数对象(function objects),而且以巧妙而且不失高效的设计模式将它们连贯在一块儿,程序员能够经过使用STL来更为快速的开发高效的程序。

  因此不能简单的讲C++认为是一个语言,而是时刻注意它4个部分不一样的规则,而且利用它们来完成更好的设计。数组

建议 02 :尽可能用const, enum, inline来替换 #define编程语言

Prefer consts, enums, and inlines to #defines

  这条建议是全部像我同样习惯C开发转向C++开发的程序员,在C程序中,为了让程序更简单修改,减小简易函数的栈开销,经常会使用#define来声明宏变量或者宏函数,可是在C++中,这是不被提倡的,由于#define定义的宏在预编译阶段展开,不会将它描述的变量生成在符号表(symbol table)中,同时,若是使用宏来描述一个浮点型常量,预编译处理器可能会盲目替换代码中对应的浮点数宏变量,虽然这样就不须要为其分配内存,可是事实上代码存储也是须要内存的,反而得不偿失。函数

  另外, 须要注意的是在类中对const参数的初始化,通常来讲,常量值使用声明式在头文件中完成声明。工具

  能够在声明时初始化:学习

class GamePlayer {
private:
    static const int NumTurms = 5;   //为了使得常量只有一份实体
    ...
}

或者在类中声明,类外初始化

struct GamePlayer {
private:
    static const int Numturms; //声明式 头文件(.h)声明
    ...
}

const int GamePlayer::Numturms = 5;  //实现文件初始化(cpp/cc)

  一个比较有趣的操做是emum补偿,编译器必需要在编译期间得到数组的大小,有的编译器不容许“static int class” 常量” 完成 "int class 初始化操做" ,就是不能使用class内的static int 常量来做为数组大小,此时就能够曲线救国,使用所谓的“the enum hack”补偿作法,其理论基础是,一个属于枚举类型(enumerated type)的数值可被当作int使用,因此能够这样声明数组:

class GamePlayer {
private:
    enum { Numturms = 5 };   //"the enum hack" 讲NUmturms 做为5的记号
    int scores[Numturms];    //声明数组
}

  enum hack有多种用途,认识它是十分有必要的。enum hack的行为比较相似与#define 而不是const,即它在内存中没有实体,只是做替换功能,因此不能对它取地址,这样也从某种角度实现了一种约束,指针没法指向它,根据编译器的不一样,有的编译器会对const对象设定另外的存储空间(没有指针和引用指向的状况下),有的编译器则会,可是使用enum hack却能够保证不会有这部分的额外开销。

  enum hack仍是template metaprogramning(模板元编程)的基础技术。


在什么状况下替换

对于单纯的常量,最好使用const 对象或者enum来替换#define 对于相似与函数的宏(macros),最好使用inline函数替换#define,虽然这样编译器会选择是否内联,可是这也是咱们想要的。
相关文章
相关标签/搜索