Effective C++读书笔记

Scott Meyers是C++写作方面的大牛,effective c++这本书也算是业界知名,重读笔记之。

  • 区分declaration and definition. Declaration的目的是告诉编译器声明的标识符的类型。比如extern int bar; double f(int, double); 而definition是declaration的具体实现,linker需要把definition的实现链接到它的引用。通常情况下C++要去所有的变量都需要先declare再提供definition,然后才能使用。唯一的例外是声明在class中的static int/char/bool 类型的变量,比如class A { static int key = 5; } 是允许的,算是没有definition直接使用declared的例子。如果编译器不通过,那么你只能把definition补到.cpp文件中,类似于 int A::key; 注意如果declare的过程中已经给key赋值了,那么definition的时候就不必再次赋值了。但是如果declare的时候没有赋初值,那么在definition的部分可以赋初值。
  • const cast来避免重复代码。在c++中,const会被编译器用来区分函数。因此假设我们有一个class TextBlock,其中有两个member function: 第一个是const char& operator[] (std::size_t position) const; 第二个是char& operator[](std::size_t position); 两个函数的区别就在于第一个方法多出两个const关键字,于是就有了个两个overloaded functions. 但是两个函数内部干的事情可能都是差不多的,所以我们希望避免复制代码,解决方案就是在non-const版本的operator[]中调用const版本的operator[],然后做const cast. 于是第二个函数的实现就是 return const_cast<char&>(static_cast<const TextBlock&>(*this)[position]); 最外面的const_cast很好理解,把const operator[]返回的const char&类型转化为char&类型,内部的static_cast是把当前的non const this转化成const对象然后才能调用const版本的operator[],没有这个转化,那么函数就变成递归调用自己了。关于cast away const,个人理解还是尽量少用(除非你明确知道没有负面影响),毕竟const代表者client和library的协议,哪些是可以修改的,哪些不可以。
  • class内部变量初始化顺序。对于非static变量来说,初始化顺序是确定的,父类的内部变量首先被初始化,然后是子类的内部变量。注意c++中的build-in type (int, bool, char)的初始化值是非固定的,所以最好在constructor中用member list将所有内部变量都初始化确定值。对于static member,不同translation unit(the code giving rise to a single object file)中的static member初始化顺序不固定,因此如果static变量的使用中需要使用其他static变量,尽量将被使用的static变量变成local static variable(声明在函数内部的static变量,这样初始化是被保证的,通常使用singleon pattern,但是同样需要注意多线程时候的race condition).

posted on 2013-03-14 00:48  梁霄  阅读(162)  评论(0)    收藏  举报

导航