1、资源和智能指针

1.1 资源获取即初始化(RAII)原则

资源获取即初始化(RAII, Resource Acquisition Is Initialization)。
资源(堆内存、文件句柄、套接字等)应由对象“拥有”。 该对象在其构造函数中创建或接收新分配的资源,并在其析构函数中将此资源删除RAII 原则可确保当所属对象超出范围时,所有资源都能正确返回到操作系统。
通俗理解:当你获得一个资源的时候,不管这个资源是对象、内存、文件句柄或者其它什么,你都会在一个对象的构造函数中获得它,并且在该对象的析构函数中释放它。实现这种功能的类,我们就说它采用了”资源获取即初始化(RAII)”的方式。这样的类常常被称为封装类。

  • 对RAII原则的简单应用:智能指针、标准库容器(STL)

    1.2 智能指针

  • std::unique_ptr

  • std::shared_ptr
  • std::week_ptr

2、统一初始化(括号初始化)

在现代 C++ 中,可以使用任何类型的括号初始化。 在初始化数组、矢量或其他容器时,这种初始化形式会非常方便。 在下面的示例中,使用三个 S 实例初始化 v2。 v3 将使用三个 S 实例进行初始化,这些实例使用括号初始化自身。 编译器基于 v3 声明的类型推断每个元素的类型。

  1. #include <vector>
  2. struct S
  3. {
  4. std::string name;
  5. float num;
  6. S(std::string s, float f) : name(s), num(f) {}
  7. };
  8. int main()
  9. {
  10. // C-style initialization
  11. std::vector<S> v;
  12. S s1("Norah", 2.7);
  13. S s2("Frank", 3.5);
  14. S s3("Jeri", 85.9);
  15. v.push_back(s1);
  16. v.push_back(s2);
  17. v.push_back(s3);
  18. // Modern C++:
  19. std::vector<S> v2 {s1, s2, s3};
  20. // or...
  21. std::vector<S> v3{ {"Norah", 2.7}, {"Frank", 3.5}, {"Jeri", 85.9} };
  22. }

3、移动语义

一句话:资源的所有权转移
现代 C++ 提供了移动语义,此功能可以避免进行不必要的内存复制。 移动操作会将资源的所有权从一个对象转移到下一个对象,而不必再进行复制。 一些类拥有堆内存、文件句柄等资源。 实现资源所属的类时,可以定义此类的移动构造函数移动赋值运算符。 在解析重载期间,如果不需要进行复制,编译器会选择这些特殊成员。 如果定义了移动构造函数,则标准库容器类型会在对象中调用此函数。