Effective C++学习笔记(第一章)
2022-02-23 本文已影响0人
crazyhank
条款01:视C++为一个语言联邦
C++是四个次语言的联邦,它们是:
- C:传统的区块(blocks)、语句(statements)、预处理器(preprocessors)、内置数据类型(built-in data types)、数组(arrays)、指针(pointers)均来自C。
- Object-Oriented C++:提供面向对象的功能,诸如类、封装、继承、多态、虚函数等概念。
- Template C++:模板是泛型编程的基础,威力强大。
- STL:STL是个特殊的Template程序库,提供容器、迭代器、算法以及函数对象。
条款02:尽量以const,enum,inline替换 #define
- 在代码中如果以define形式定义一个常量,则会给程序带来不好调试的问题,因为它不会出现在程序的符号表中。而如果以const方式定义一个变量则可以解决这个问题,比如:
// 原代码
#define PI 3.14
替换为:
const double PI = 3.14;
使用const变量代替define还有一个好处是可以加入作用域,比如在一个类中定义一个该类专有的变量,如:
class A {
private:
static const int MyVar = 10;
};
注意:一般来说在类的声明中包含一个static const变量,需要在实现文件中再给出定义,但很多编译器现在已经支持直接在类的声明(即头文件中)直接定义。
- 使用enum变量也可以代替define的功能,比如以下代码,需要定义一个数组,编译器需要提前植到数组的大小。
enum { Num = 5; };
int Array[Num];
- 我们常用define定义一个宏函数,这时候也建议使用inline内联函数替代。宏函数非常容易出错,比如展开后的括号问题,并且不具有函数特性,而使用inline函数就可以完美解决,并且不会带来额外的函数调用开销,而且与模板功能可以一起用,威力更加强大,比如:
template<typename T>
inline void callWithMax(const T& a, const T& b)
{
f(a > b ? a : b);
}
- 最后要说明的是define这种形式还不能完全消失,比如#ifdef/#ifndef这种宏定义还是需要的。
条款03:尽可能使用const
- const修饰的位置不一样表示不同的含义,比如指针。在*号之前则表示它指向的内容是不可修改的,在*号之后则表示变量本身是不可以被修改的。
- 我们在传递参数给函数时,如果不希望在这个函数执行的时候,该变量被修改,应该推荐使用const T& xx的方式。
- 类的成员函数在末尾可以使用const修饰,表明该函数不能修改除static成员变量之外的所有成员变量。
条款04:确定对象被使用前已先被初始化
- C++内置类型一定要进行手动的初始化,比如int,bool这些类型的变量。
- 初始化和赋值是不一样的,比如:
class A {
public:
A() : val_(0) { // 这里是初始化
val_ = 10; // 这里是赋值
}
private:
int val_;
};
- 类的成员变量初始化的顺序与声明的顺序一致。
- non-local的static对象在构造时,系统不能保证先后顺序,建议使用local static对象,即提供一个函数,在该函数中返回这个local static对象,并且最新的C++ 11保证了多线程的竞争安全性。原书中还是老的C++标准,描述是有点问题的。