理解 cpp 是如何进行类型推导的,这样在使用时才不会踩太多坑……
Effective C++ :管理资源
这里的资源主要是:内存、文件描述符、互斥锁、数据库连接、socket 等,一旦不使用它们,都要归还给系统。
Effective C++ :智能指针
传统指针具有以下缺陷:
- 单从一个指针的声明,无法判定它是指向一个对象还是指向一个包含该对象的数组
- 单从一个指针的声明,无法判定当不使用该指针时,是否需要释放它所指向对象所占用的资源
- 当需要释放指针所指向对象的资源时,并不能明确的知道是该使用
delete
,还是使用其它专有的释放函数 - 当需要使用
delete
释放资源时,到底是使用delete
还是delete[]
,这需要小心使用,否则会造成内存泄漏或未定义行为 - 当确定了释放机制时,也有可能写代码时一不小心,就造成了 double free
- 当释放一个资源时,有可能还有其它指针(Dangling pointers)指向该资源,从而导致很多很难查的 BUG
使用智能指针变能够最大化的避免以上问题。
Effective C++ :构造,析构和继承
- 构造和析构函数中调用虚函数,由于其派生类还未被构造和已被析构,所以得到的结果不会是预期的。
- 重载父类虚函数,需要加上
override
关键字
Effective C++ :赋值重载的注意点
复制重载涉及到拷贝赋值和移动赋值两种情况,有些点需要注意一下。
Effective C++ :delete 优于私有未定义行为
Effective C++ :异常的注意点
Effective C++ :为多态基类声明 virtual 析构函数
为保证多态析构的正确性,需要为基类的虚构函数加上virtual
:
1 | #include <iostream> |
Effective C++ :认识编译器的默认生成函数
编译器默认会为一个类提供(如果它们需要被使用的话):
- 默认构造函数:如果类编写了构造函数,则编译器就不会自动提供默认构造函数了
- 使用
default
显示声明也可以在有其他构造函数的情况下,让编译器产生默认构造函数
- 使用
- 拷贝构造函数:没有移动函数显示定义时,拷贝函数才会被隐式的创建。其单纯地将每一个数据成员进行拷贝
- 如果数据成员中的对象具有它自己的拷贝构造函数,则也会调用它
- 拷贝赋值函数:单纯地将每一个数据成员进行拷贝
- 如果数据成员中的对象具有它自己的拷贝赋值函数,则也会调用它
- 析构函数:隐式的
noexcept
- 移动构造函数:当没有显示定义移动、拷贝、析构函数时,默认移动函数才会被隐式的创建
- 移动赋值函数
生成的特殊函数是隐含的public
和inline
的,但大部分情况下都是非虚函数。
>
只有当一个类继承自基类,基类的析构函数是虚函数时,生成派生类的析构函数才也是虚函数
Effective C++ :对象的初始化
要养成好的习惯:永远在使用对象之前先将它初始化。 - 对于内置类型,在定义时就初始化 - 对于类类型,在构造函数初始值列表中按照声明顺序初始化 + 类类型中的私有变量是内置类型时,也可以在声明时初始化,这样可以避免初始值列表过长。 + 如果期望类类型中的对象以默认构造函数初始化时,那也可以不用放在初始值列表中