Effective C++(第三版)读书笔记
文章目录
改善程序与设计的55个具体做法,作者是侯捷。
这本书是分为9个模块阐述使用规范,其实它就是一种写代码时的软规范,遵循这些规范能比较好的规避一些错误,有些能增加代码效率。目前我还未看完,我比较感兴趣的是“资源管理”、“设计与声明”、”模板与泛型编程”,所以会在下面重点介绍这几模块,其他的模板还只作不求甚解。
1. 让自己习惯C++
01.视C++为一个语言城邦
C++的次语言可分为C部分, OOC++部分,Template C++部分和STL部分共四部分。
- C部分
以C语言为基础,包括区块(blocks)、语句(statements)、预处理器(preprocessor)、内置数据类型(built-in data types)、数组(arrays)、指针(pointers)。 - Object-Oriented C++
classes(包括构造和析构函数),封装(encapsulation),继承(inheritance),多态(polymorphism),virtual函数(动态绑定)等等。 - Template C++
泛型编程(generic programming)部分,编程泛型(programming paradigm),也就是metaprogramming(TMP 模板元编程)。 - STL
STL是个Template程序库,它对容器(containers)、迭代器(iterators)、算法(algorithms)以及函数对象(function objects)的规约有极佳的紧密配合与协调。
02. 尽量以const, enum, inline 替换 #define
- 对于单纯常量,最好以const对象或enums替换 #defines
- 对于形似函数的宏(macros),最好改用inlines 函数替换#defines
03. 尽可能使用const
- 将某些东西为const可帮助编译器出错误用法。const可被施加于任何作用域内的对象、函数参数、函数返回类型、成员函数本体。
- 当const和non-const 成员函数有着实质等价的实现时,令non-const 版本调用const版本可避免代码重复。
栗子:
char greeting[] = "Hello";
char* p = greeting; //non-const pointer, non-const data
const char* p = greeting ; // non-const pointer, const data
char* const p = greeting; //const pointer, non-const data
const char* const p = greeting; //const pointer, const data
总结就是:星号区分两边,左为data,右为pointer
04. 确定对象被使用前已经被初始化
区分赋值(assignment)和初始化(initialiization)
//assignment
ABEntry::ABEntry(const std::string& name,const std::string& address,
const std::list<PhoneNumber>& phones){
theName = name;
theAddress = address;
thePhones = phones;
numTimesConsulted = 0;
}
//initilization
ABEntry::ABEntry(const std::string& name,const std::string& address,
const std::list<PhoneNumber>& phones):
theName(name),theAddress(address),thePhones(phones),numTimesConsult(0){
}
赋值和初始化的区别在于,赋值需要两步先调用default构造函数设置初值再赋于新值、
而初始化就是将address值进行copy构造。一般来说,后者更高效。
2. 构造、析构、赋值运算
05. 了解C++默默编写并调用哪些函数
编译器可以为class默认创建default 构造函数,copy 构造函数,copy asignment 操作符,以及析构函数。
Empty类定义
class Empty{
public:
Empty(){} //default构造函数
Empty(const Empty& rhs){} //copy 构造函数
~Empty(){} //析构函数
Empty& operator=(const Empty& rhs){} //copy assignment 操作符
};
Empty使用
Empty e1;
Empty e2(e1);//copy 构造函数
e2 = e1;//copy assignment 操作符
06. 若不想使用编译器自动生成的函数,就该明确拒绝
实现并声明为private,
class Uncopyable{
private:
Uncopyable(const Uncopyable&);
Uncopyable& operator=(const Uncopyable&);
};
07. 为多态基类声明virtual析构函数
- polyjmorphic (带有多态性质的) base class 应该声明一个virtual 析构函数,如果class带有任何virtual函数,它就应该拥有一个virtual析构函数。
- Classes 的设计目的不是多态或者base class 就不该声明virtual 析构函数。
下列未完成。