第 11 章. 类 :特殊成员函数 与移动语义
在第 10 章中,你编写了自己的类,并发现编译器可以为你生成特殊的成员函数,例如构造函数和析构函数。 本章将向你介绍 C++ 中的其他特殊成员函数,说明它们何时使用,以及为何重要。
本章将深入探讨,并解释一些重要概念,包括移动语义:一种通过资源转移来提高代码效率的方法。
目前,你的Stock类已经运行良好,但花时间理解其工作原理将为你打下坚实的C++基础。
你还将详细了解std::string的工作原理,并观察每个特异成员函数的运行过程。
这将向你展示 C++ 为何为类提供各种特异成员函数,以及它们的作用。
对象的复制
在上一章的示例 10-4 中,你创建了一个包含股票的 `` 向量,如示例 11-1 所示。
示例 11-1. 来自初始化列表的股票向量
#include<vector>#include"stock.h"intmain(){usingnamespacestock_prices;std::vectorstocks{Stock{"Coffee",4.8,0.0113},Stock{"Tea",171.68,0.023},Stock{"Sugar",17.91,0.05}};}
这段代码调用了三次构造函数,但调用了六次析构函数。
初始化列表包含三个对象,它们被复制到std::向量中。
复制是通过名为“复制构造函数”的 特异成员函数实现的,该函数旨在复制现有对象。
图 11-1展示了复制后最终会产生两个对象,因此原始的三个对象需要与三个副本一同销毁。
图 11-1. 复制 对象
让我们来详细看看复制过程。 编译器可以为你提供一个具有以下签名的复制构造函数:
Stock(constStock&other);
与您迄今为止使用过的其他构造函数一样,复制构造函数的名称与类名相同。
它接受一个参数——即您要从中复制的另一个(或原始)对象,并据此构建一个新实例。
该参数other 是一个现有对象,因此您可以在此函数中复制其中部分或全部成员。
您可以编写自己的复制构造函数,但在此处无需这样做。
默认构造函数已能满足您的需求。
只有在特定情况下才会获得默认复制构造函数(),因此能够显式请求复制构造函数()非常有用。你可以使用default 来请求复制构造函数:
Stock(constStock&other)=default;
你也可以使用 `delete` 来禁用复制:
Stock(constStock&other)=delete;
尝试在你的代码中禁用复制,方法是在 stock 头文件中添加= delete声明。
主程序将无法编译,因为无法再从初始化列表中复制股票对象。
有时您可能希望避免进行复制。
如果复制股票,最终会产生两个对象,当调用next_price 时,它们的价格将出现偏差。
这毫无意义——股票的价格应该是一个值。
如果无法复制 `Stock`,该如何创建`Stock`的向量?
自 C++11 起,C++ 提供了一个特殊的成员函数,允许你通过“移动”另一个实例来创建 `` 对象。
让我们看看具体如何操作。
移动对象
在 C++ 中,移动对象具有非常特定的 C++ 含义。 从宏观层面来看,你可以使用
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access