c++ - C++11 的移动语义是否优于写时复制习惯用法?

标签 c++ c++11 idioms

我在这里可能会感到困惑,但我确实理解的是:

  • COW 将返回一个“假”拷贝,直到其中一个调用者想要进行一些修改。
  • 在所有情况下,Move Semantic 都会返回“假”拷贝。

因此,如果我的目的是拥有一个只需要读取而不更新的对象,我应该只等待我的 C++ 编译器支持移动语义?

我说得对吗?

最佳答案

移动语义不会返回“假”拷贝。相反,在复制操作中,它允许被复制者删除原始拷贝。

一个激励性的例子可能具有启发性:

std::vector<int> bigData;

// fill bigData

std::vector<std::vector<int> > listOfData;

listOfData.push_back(std::move(bigData));
// after this point, the contents of bigData are unspecified (however accessing it is _not_ undefined behavior)

如果没有移动语义,您需要复制 bigData 以将其插入到 listOfData 中,或者手动使用 swap() 将其插入到 listOfData 中的新空 vector 中。但是对于移动语义,std::vector 的右值引用构造函数(又名移动构造函数)在复制新数据时由 push_back 调用,有权丢弃 bigData 的旧内容 - 因此,允许窃取 bigData 的内部指针并将 bigData 重置为空 vector ,例如。

移动语义通常比 COW 语义更快,因为它们不需要维护共享的只读数据的引用计数。然而,它们的局限性更大——您无法使用移动语义为您的数据创建多个引用计数别名,您可以轻松方便地在容器之间随机播放数据。

另请注意,最新版本的 GCC 和 Microsoft Visual C++ 都支持右值引用和移动语义(GCC with --std=c++0x),因此没有理由不开始使用它们今天。

关于c++ - C++11 的移动语义是否优于写时复制习惯用法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8426257/

相关文章:

c++ - 如何使 clang-format 将所有详细命名空间缩进一个

c++ - 如何使 C++ 模板函数与返回类型无关以供将来专门化

c++ - move 语义可以帮助构建在 std::array 上的用户定义容器吗?

Ruby - 将变量传递给 eval 方法

c++ - 为什么派生类函数参数采用基类函数参数的值?

c++ - visual studio 2015 无法编译有效代码(标准函数错误?)

c++ - 在 CMake 中仅指定某些源文件

c++ - 在 C++ 中添加字符串和文字的问题

if-statement - 其他人真的是代码味道吗?编写 Go 条件的惯用方式

python - 分配给 "_ "的原因