版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_40028201/article/details/89673249
Effective C++ 读书笔记(一)
1、让自己习惯C++
条款 01 :视C++为一个语言联邦
C++的四个层次:
- C:C++是在C语言的基础上发展而来的
- Object-Oriented C++:这是C++中不同于C的部分,这里主要指面向对象。
- Template C++:C++中的泛型编程。
- STL:这是一个标准模板库,它用模板实现了很多容器、迭代器和算法,使用STL往往事半功倍。
条款 02: 尽量const、enum、inline替换#define
-
const好处
- define直接常量替换,出现编译错误不易定位(不知道常量是哪个变量)
- define没有作用域,const有作用域提供了封装性
-
enum好处:
- 提供了封装性
- 编译器肯定不会分配额外内存空间(其实const也不会)
-
inline的好处:
-
define宏函数容易造成误用(下面有个例子)
//define误用举例 #define MAX(a, b) a > b ? a : b int a = 5, b = 0; MAX(++a, b) //a++调用2次 MAX(++a, b+10) //a++调用一次
-
-
注意:
- 对于单纯的常量,最好以const对象或enums替换#define
- 对于形似函数的宏,最好改成内联函数
条款 03 :尽可能使用const
-
const修饰的变量不允许改变
-
注意指针常量与常量指针,stl中的迭代器类似指针(T* const point,指向的元素可以修改)
-
const成员函数
-
可以确认类中哪些成员函数可以修改数据成员
-
const对象只能调用const 对象成员函数,非const对象既可以调用普通成员函数也可以调用const成员函数(这是因为this指针可以转化为const this,但是const this 不能转化为非 const this)
扫描二维码关注公众号,回复: 6057791 查看本文章 -
一个函数是不是const是可以被重载的
-
更改了指针所指物的成员对象不算是const,但是如果只有指针属于对象,则成函数为bitwise const 不会发生编译器异议
-
用mutable关键字修饰的成员变量,将永远处于可变状态, 哪怕是在一个const函数中
-
如果const和非const成员功能类似,用非const版本调用const版本,避免代码复制;
class CTextBlock{ public: const char& operator[](std::size_t position)const { ... return pText[position]; } char& operator[](std::size_t position) { return const_cast<char&>(static_cast<const CTextBlock&>(*this)[position]); } char * pText; int length;
-
条款 04 : 确定对象使用前已被初始化
- 有些情况下会初始化为0 ,有时候不会被初始化
- 内置类型,手工初始化
- 内置以外的类型,构造函数初始化
- 构造函数体内的是赋值,初始化列表中才是初始化
- 初始化顺序要和声明顺序一致
- 初始化的效率高于赋值
- 赋值是先定义变量,在定义的时候已经调用的变量的默认构造函数之后是用了赋值操作符;
- 初始化时直接调用了拷贝构造函数
- const、引用、基类传参(因为基类先于派生类初始化)、对象成员必须在初始化列表中
- 函数体内的static对象是local static对象,其他static对象是non-local static对象
- 定义在不同编译单元内的non-local static对象”初始化次序无明确
- static对象只有一份拷贝,且只初始化一次(类似于单例模式)使用local static对象,首次使用时初始化,返回其引用即可(local static声明周期是整个程序),以后再使用无需再次初始化。
- 总结:
- 手动初始化non-member对象
- 使用初始化列表初始化member对象。
- 消除初始化次序的不确定性。