前言(废话):今天开始读<<Effective C++>>这本书。这个笔记主要是对书里的条款记录自己的理解,同时回复一些C++基础知识。
条款0的C++基本概念:
**1.隐式类型转换的问题**
隐式转换是编译器执行的,不是程序员能控制的。
"可以用单个实参来调用的构造函数定义了从形参类型到该类型的一个隐式转换。" --- <<C++ PRIMER>>
翻译的非常拗口难懂,今天查资料才弄明白。上面的话的意思是:如果一个类的构造函数可以用单个实参来调用的话,那么这个形参的类型和这个类的类型之间就有一个隐式转换。比如说:
class person{
string name;
int age;
bool isSameAge(persong &otherperson) {
return age == otherperson.age;
}
person(const string &n, const int &a=20):name(a),age(a){}
};
person p1("liu");
person p2("zhang");
std::cout << p1.isSameAge(p2) << std::endl //可以,形参实参类型相同
std::cout << p1.isSameAge(string("zhang")) << std::endl //也可以,因为person虚构函数是单参,所以它的形参类型会隐式转换成它本身的类型(person类型.
而书上的条款0上就鼓励我们采用阻止执行隐式类型转换。而方法很简单,就是在类的构造函数前面加上explicit关键字。所以如果上面代码中的构造函数改成
explicit person(const string &n, const int &a):name(n),age(a){}
编译器就会报错。
2.尽量以const,enum,inline替换#define
书上例子:
#define PI 3.1415926
const double PI = 3.1415926;
这两个的区别在于找bug的时候。对于#define而言,如果这个地方出错了,那么编译器提供的信息一般是3.1415926的错误,而对于const则是提示PI的错误。也就是说#define定义的名字并不进入到符号表(编译器里的东东),而const常量则会。这样给调试程序带来了方便。
有些旧的编译器不允许static成员在声明式中获得初值,而C++声明数组的时候又必须指定数组的大小,这样就会出现矛盾。解决方法就是采用enum.
enum {arrayLen = 5}; //多个枚举元素的话,依次递增,而且中间以,间隔
int array[arrayLen]; //允许
书上还介绍了一个inline,称为内联函数。
我们知道其实如果有些短小的表达式如果用#define来定义的话容易出现各种各样的小错误(尤其是变量括号的问题),但是短小表达式写成函数形式的话调用起来又会引起不必要的运算。C++提供了一个inline函数,如下:
inline int bigger(int &a, int &b) {
return a>b?a:b;
}
这样既不用在a,b参数上加括号,又能高效解决问题。