1、资源和智能指针
1.1 资源获取即初始化(RAII)原则
资源获取即初始化(RAII, Resource Acquisition Is Initialization)。
资源(堆内存、文件句柄、套接字等)应由对象“拥有”。 该对象在其构造函数中创建或接收新分配的资源,并在其析构函数中将此资源删除。 RAII 原则可确保当所属对象超出范围时,所有资源都能正确返回到操作系统。
通俗理解:当你获得一个资源的时候,不管这个资源是对象、内存、文件句柄或者其它什么,你都会在一个对象的构造函数中获得它,并且在该对象的析构函数中释放它。实现这种功能的类,我们就说它采用了”资源获取即初始化(RAII)”的方式。这样的类常常被称为封装类。
2、统一初始化(括号初始化)
在现代 C++ 中,可以使用任何类型的括号初始化。 在初始化数组、矢量或其他容器时,这种初始化形式会非常方便。 在下面的示例中,使用三个 S 实例初始化 v2。 v3 将使用三个 S 实例进行初始化,这些实例使用括号初始化自身。 编译器基于 v3 声明的类型推断每个元素的类型。
#include <vector>struct S{std::string name;float num;S(std::string s, float f) : name(s), num(f) {}};int main(){// C-style initializationstd::vector<S> v;S s1("Norah", 2.7);S s2("Frank", 3.5);S s3("Jeri", 85.9);v.push_back(s1);v.push_back(s2);v.push_back(s3);// Modern C++:std::vector<S> v2 {s1, s2, s3};// or...std::vector<S> v3{ {"Norah", 2.7}, {"Frank", 3.5}, {"Jeri", 85.9} };}
3、移动语义
一句话:资源的所有权转移
现代 C++ 提供了移动语义,此功能可以避免进行不必要的内存复制。 移动操作会将资源的所有权从一个对象转移到下一个对象,而不必再进行复制。 一些类拥有堆内存、文件句柄等资源。 实现资源所属的类时,可以定义此类的移动构造函数和移动赋值运算符。 在解析重载期间,如果不需要进行复制,编译器会选择这些特殊成员。 如果定义了移动构造函数,则标准库容器类型会在对象中调用此函数。
