《Effective C++》 笔记:Tips01-Tips04

Tip01C++为一个语言联邦

CC++是以C为基础,这一部分就是基础的C,没有模板(template),没有异常(exceptions),没有重载(overloading)编程


Object-Oritented C++:即C with Class,面向对象部分。ide


Template C++C++的泛型编程函数


STL:一个template程序库。this


编程守则:spa

1.对于C而言,由于C中没有Object的概念,所以值传递(pass-by-value)比引用传递(pass-by-reference)高效。指针

2.对于Object-Oritented C++Template C++,因为有了构造函数和析构函数的存在,pass-by-reference-to-const更好调试

3.对于STL,由于迭代器和函数对象都是在C指针上构建的,因此旧式的C pass-by-value再次适用对象


Tips02:尽可能以const,enum,inline代替#define

1、缘由一:#define使用的名称可能未进入记号表(symbol table),致使调试困难。ip


2、enum hack的用法。编译器

在某些旧式编译器上,可能不容许static成员在其声明式上得到初值。固然,能够将初值放在定义式上。

然而,class编译期间须要一个class常量。如

class GamePlayer{
private:
static const int NumTurns = 5;
int scores[NumTurns];
}

若是编译器不经过static const int NumTurns = 5;就须要用到enum hack

class GamePlayer{
private:
enum {NumTurns = 5};
int scores[NumTurns];
}

补充一点,初始化static成员变量。在头文件,类定义中声明static变量

static T sMember

而后在源文件(.cpp)定义该static变量

T Class::sMember = value


3、#define定义的函数宏,最好用inline+tepmlate替代

#define CALL_WITH_MAX f((a) > (b) > (a) : (b))
int a = 5 , b = 0;
CALL_WITH_MAX(++a, b)  a = 7;
CALL_WITH_MAX(++a, b+10)  a = 6;

a的递增次数取决于和谁比较。

++ab++a=6a>b,返回(++a)a = 7;

++ab+10++a=6,a<b+10,返回(b), a = 6


Tip03:尽量使用const

1、成员函数是const的含义,Class::Function() const

1.bitwise constness:成员函数不能改变任何成员变量,也就是说不能更改对象的任何一个bit

可是若是,成员变量是指向对象的指针,按照bitwise的观点,成员函数不能改变该指针,至关于在该成员函数内,指针是指针常量。然而,在const成员函数内,却能够改变指针指向的对象。

可是,const成员函数的初衷,就是防止改变指针指向的对象。

PS:编译器就是bitwise constness

2.logical constnessconst成员函数能够修改为员变量,但只有编译器经过的状况下。

既然成员函数是const,对于编译器而言,它就毫不能修改为员函数,如何让它能经过编译器检查呢?在成员变量添加修饰符mutable,能够释放掉成员变量的bitwise constness约束。也就是说,即便在const成员函数内,也能够修改mutable成员变量。


2、non-const版本调用const版本。

一般const版本的non-const的函数实现是同样的,惟一的不一样是返回类型。这时,咱们能够在non-const版本调用const版本。

(*this)转换为const类型static_cast<const T>(*this)。这样就才能调用const版本的函数

static_cast<const T&>(*this).function()

const版本的返回值(const T&)转换成non-const

const_cast<T &>( static_cast<const T&>(*this).function())//(*this)返回的是reference of T

3、为何non-const版本不能调用const版本

const成员函数绝对不会改变对象的逻辑状态(logical state)non-const成员函数却没这条限制。若是const版本调用non-const版本,就会发生const函数内改变了对象的逻辑状态,无论实际上有没有改变,这彻底取决于non-const版本


Tip04:肯定对象被使用前初始化

1、赋值(assignment)和初始化(initialization)的区别

XXX::XXX(){
   Member1 = xxx;
   Member2 = xxx;
}

这叫赋值。而Java中不存在初始化列表,所以只能采用这种初始化方式,因此在Java的初始化对应的是C++的赋值


2、初始化的顺序

类的成员变量老是以其声明的方式被初始化。即类中声明的顺序是A,B,C,D…,那即便初始化列表的顺序是B(xxx),D(xxx),C(xxx),A(xxx),实际初始化顺序依然是A,B,C,D


3、什么是non-local static对象。

通常声明在函数内部的变量,称之为局部变量或者本地(local)变量。因此,non-local static对象,就是在函数体以外声明的static对象


4、non-local static对象的初始化顺序。

对于把不一样的编译单元内的non-local static对象的初始化顺序根本,没有明肯定义。


5、若是其余类用到了non-local static对象,但不能肯定该对象是否初始化,怎么解决。

local static对象替换non-local static对象。C++保证,函数内的local static对象会在“该函数被调用期间”“首次遇到该对象之定义式”时被初始化。用函数调用(返回一个reference指向local static对象)替换non-local static对象,那么该reference必定指向了一个历经初始化的对象

相关文章
相关标签/搜索