共享内存和写入时复制或右值引用以及移动语义?
通用容器(如 Qt 容器中的容器)的共享内存/写入时复制实现是否被 C++11 移动语义和右值引用取代?
Is a shared memory/copy on write implementation for general containers (like that found in Qt's containers) superseded by C++11 move semantics and rvalue references?
一个失败而另一个成功的地方在哪里?还是它们是互补而非替代?
Where does one fail and the other succeed? Or are they complementary rather than alternatives?
推荐答案
写入时复制和移动语义都已用于优化将数据保存在堆上的对象的值语义.例如,std::string
既被实现为写时复制对象,又被实现为启用移动的对象.
Both copy on write and move semantics have been used to optimize value semantics of objects that hold their data on the heap. std::string
, for example has been implemented both as a copy-on-write object, and as a move-enabled object.
所以写时复制和移动语义在这方面是相似的:如果你足够松散地定义复制",它们都可以用来优化复制".我有时将移动语义描述为写时复制,引用计数被限制为 0 或 1,因此包含引用计数的字段被优化掉了.
So copy-on-write and move semantics is similar in that regard: they can both be used to optimize "copies" if you define "copy" loosely enough. I've sometimes described move semantics as copy-on-write with the reference count being limited to 0 or 1, and thus the field containing the reference count is optimized away.
std::lib 中的所有容器现在都使用移动语义,甚至以前允许使用写时复制的 std::string
现在也被禁止这样做.如果我今天要编写一个新的客户容器,我会在选择写时复制之前使用移动语义.
All of the containers in the std::lib now use move semantics and even std::string
, which used to be allowed to use copy-on-write, is now forbidden from doing so. If I were writing a new customer container today, I would use move semantics before choosing copy-on-write.
在 C++11 中仍然可以使用写时复制.如果您希望您的数据结构很少被写入,但经常被复制,并且许多客户持有相同值的副本,那么写时复制仍然是一个巨大的胜利.
There is still a use for copy-on-write in C++11. If you expect your data structure to be rarely written to, but copied often, with many clients holding copies of the same value, copy-on-write can still be a large win.
例如,我看到写时复制很好地用于保存复杂文档的撤消列表.在任何给定的提交(您要保存状态的地方),自上次提交以来,只有一小部分大文档发生了变化.因此,制作文档副本以保存其状态意味着更新一堆引用计数,并实际对一小部分进行更改(写入时复制样式).
For example I've seen copy-on-write put to good use to hold an undo-list for a complex document. At any given commit (where you want to save state), only a small piece of the large document has changed since the last commit. So making a copy of the document to save its state means updating a bunch of reference counts, and actually making changes (copy-on-write style) to a small piece.
相关文章