共享内存和写入或右值引用上的副本和移动语义?

rub*_*nvb 8 c++ containers copy-on-write shared-memory rvalue-reference

一般容器的写入实现的共享内存/副本(如在Qt容器中找到的那样)被C++ 11移动语义和右值引用所取代?

哪一个失败而另一个成功?或者它们是互补的而不是替代品?

How*_*ant 7

写入和移动语义上的复制都已用于优化将数据保存在堆上的对象的值语义. std::string例如,已经实现为写入时复制对象和启用移动的对象.

因此,写时复制和移动语义在这方面是类似的:如果你足够松散地定义"复制",它们都可以用来优化"复制".我有时将移动语义描述为写入时复制,引用计数限制为0或1,因此包含引用计数的字段被优化掉.

std :: lib中的所有容器现在都使用移动语义,甚至std::string过去允许使用copy-on-write,现在禁止这样做.如果我今天正在编写一个新的客户容器,我会在选择copy-on-write之前使用移动语义.

在C++ 11中仍然可以使用copy-on-write.如果您希望您的数据结构很少被写入,但经常被复制,许多客户端持有相同值的副本,则写入时复制仍然是一个巨大的胜利.

例如,我已经看到copy-on-write很好地用于保存复杂文档的撤销列表.在任何给定的提交(您希望保存状态)中,自上次提交以来,只有一小部分大文档发生了更改.因此,制作文档的副本以保存其状态意味着更新一堆引用计数,并实际进行更改(写入时复制样式)到一小块.


Dav*_*eas 6

写时复制和移动语义是完全不同的概念,每个概念都有不同的用途.虽然有一个常见的用例:从函数返回一个对象,其中因为原始范围超出范围,它实际上是一个移动,在一般情况下它们不同:

通过复制写入多个同时处于活动状态的对象可以共享内容.使用移动语义,只有一个对象具有特定时间点的内容.

与此正交,写入时复制在多线程环境中存在问题,因为可能有多个对象访问相同的数据(只读)和控制块(读/写),需要以线程安全的方式进行管理.