视觉理解移动C++标准的语义
visual Understanding Move Semantics of C++ Standard
我正在尝试了解移动语义。我变得困惑,因为我无法找出我们为什么需要它以及我们应该如何理想地使用它。
例如,当我们用 std::move 移动一个对象时,它会使对象 nullptr。 为什么会这样?另外,为什么 std::move 将对象转换为右值?这是怎么发生的?为什么使用带有变量的 std::move 后,它不会用 null 填充它,但是当我将它与像 vector 这样的对象一起使用时,在移动它之后,它会用 nullptr 填充它。
我希望有人逐步解释CPP的移动语义和其他语义。我读得越多,我就越困惑。它是CPP编程中最复杂的主题之一。
当我们用 std::move 移动对象时
不。std::move
不会移动东西。它为我们提供了一个引用某个对象的右值表达式。右值表达式会导致重载解析选取函数,这些函数采用右值引用,这很方便,因为现在我们将选择这些函数,而不是接受值的函数或左值引用,后者传统上执行类似复制的操作。这些函数往往是构造函数(所谓的"移动构造函数")或赋值运算符(所谓的"移动赋值运算符"),因为在构造和赋值期间移动是有用的。
它使对象为空
这完全取决于所述功能的作用。通常,值得移动的对象具有间接状态,例如指向某些动态分配资源的指针。如果所述对象是可移动的,则其移动构造函数最好在这些指针上进行交换。如果它没有将源对象的指针保留为nullptr
则有两个对象拥有该资源。这不是一个举动;这是一个[浅层]副本。
关于如何和为什么的完整讨论超出了问答的范围,但任何一本好书都应该有一个。
此外,如果这一切听起来像是黑客,那是因为它是一个。C++ 是一个基于黑客构建的黑客大杂烩,随着时间的推移提供额外的功能。在这种情况下,我们需要(阅读:想要)一种方法来创建不同类型的构造函数(和赋值运算符),一种接受非const
引用并且可以修改源对象(以"窃取"其资源)的方法,并且为了实现这一点,我们必须引入一种仅绑定到右值的新型引用(因为我们已经将其他所有内容用于副本), 然后我们必须引入一个实用程序函数,它将对象的名称转换为右值......因此,std::move
诞生了,实用程序函数不会移动任何东西。
- 何时在引用或唯一指针上使用移动语义
- 使用CMake检测支持的C++标准
- 如何理解C++标准N3337中的expr.const.cast子句8
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- 编译标准库类型
- 如何从具有移动语义的类对象中生成共享指针
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- Boost Spirit,获取迭代器内部语义动作
- 编译器如何在使用SFINAE的函数和标准函数之间确定两者是否可行
- 可以使用移动语义更改或改进此C++代码吗?
- c++在使用指针时移动语义
- 铸造标准::有没有回到原来的类型
- 标准 N3337 5.2.10 第 7 条中的C++"类型"是什么意思?
- this_thread::sleep_for和计时时钟之间的关系是否由C++11标准指定
- 视觉理解移动C++标准的语义
- 标准库中是否有与 std::thread 的构造函数语义匹配的类型擦除函数包装器?
- 复制有状态分配器:标准库分配器语义和内部内存
- 标准库/模板化容器的常量语义的经验法则
- 移动语义、标准集合和构造时间地址
- 标准 C++11 是否保证"易失性原子<T>"同时具有语义(易失性 + 原子)?