C++的 STL 普通容器为什么不做 Copy on write 的特性呢?

2019-04-23 19:03:59 +08:00
 lhx2008
初学 C++,理解不对请指教。

COW,像 string 是有做的,但是 vector 这些就没有。

但是调用 vector 的拷贝构造函数(值传递,对象成员初始化)可能会经常发生,但是大部分情况下不一定会改副本。

如果每次都复制内存,会不会效率会很低呢?如果让开发者带指针传递,又增加了开发者的负担
1928 次点击
所在节点    问与答
20 条回复
0x11901
2019-04-23 19:05:45 +08:00
引用了解下。
lhx2008
2019-04-23 19:06:53 +08:00
@0x11901 给一个对象的成员变量赋值,如何使用引用呢?
lhx2008
2019-04-23 19:13:23 +08:00
@0x11901 准确来说是,引用传递进来只是少一次复制,但是如果用于成员变量初始化的情况,还是得复制的
0x11901
2019-04-23 19:13:47 +08:00
@lhx2008 那这个问题和 cpp 关系不大吧……如果是基本类型,直接值传递,如果非基本数据,一般就是传引用就够了。
lhx2008
2019-04-23 19:14:46 +08:00
@0x11901 还有就是返回值(临时对象)的时候,也可能会发生复制
0x11901
2019-04-23 19:15:20 +08:00
@lhx2008 你的意思是不同对象共享同一个非基本数据的引用?一处修改,每个对象的成员变量都会修改?
lhx2008
2019-04-23 19:16:15 +08:00
@0x11901 COW 的意思就是修改时再复制,这样不修改就不用复制
0x11901
2019-04-23 19:16:38 +08:00
@lhx2008 返回的时候如果不想触发拷贝构造,这个是你的事。
0x11901
2019-04-23 19:19:02 +08:00
@lhx2008 那应该就是标准委员会的老人们觉得没必要,各种特性争了这么多年了都没有进 c++标准,但是你可以自己实现。
lhx2008
2019-04-23 19:20:22 +08:00
@0x11901 触不触发拷贝构造,应该是看编译器优不优化吧?还是我理解有误
exonuclease
2019-04-23 19:21:15 +08:00
因为你可以重载索引操作符和拷贝构造函数自己折腾一个啊
0x11901
2019-04-23 19:24:22 +08:00
@lhx2008 如果你没有用 c++17 标准的"copy elision",完全很有可能在返回时触发拷贝构造,编译器不会优化你明确指出想要拷贝构造的地方。
secondwtq
2019-04-23 19:41:39 +08:00
C++11 已经不允许 COW string 了。

这种问题得从 C++ 特色去考虑:COW 在修改时会 invalidate 掉 iterator 和 reference
msg7086
2019-04-23 22:01:09 +08:00
因为 C 和 C++设计上就是允许你进行非常底层的操作的?
是否 Copy 完全要看调用者的需求,而不是自动处理吧。
lhx2008
2019-04-23 22:13:37 +08:00
@msg7086 事实就是这么残酷,有些时候栈上分配的部分必须 Copy。
一个方法是再用一个(智能)指针指向堆上内存,然后 Copy 的只是只用 Copy 指针,开销小一点。
如果用 COW 的话,栈上也是要复制的(很少),只是堆上部分复不复制看情况。
blinue
2019-04-23 22:22:22 +08:00
c++11 引入的移动构造和赋值事实上足以解决很多问题,更何况 cow 的引入会使迭代器的复杂度倍增,原罪在于指针!
lynskylate
2019-04-24 02:02:01 +08:00
string 的 cow 已经被认为是失败的设计了
iceheart
2019-04-24 07:03:17 +08:00
既然你有这需求了,为啥不自己实现一个这样的容器?
做好了再拿出来去打标准委员会的脸。
shihira
2019-04-24 09:19:38 +08:00
如果在业务中有这样的需求,或者拷贝成为了性能瓶颈,你可以自己写一个这样的 vector 也不费什么劲,但这不适合作为标准库。标准库就是要逻辑清晰、行为有可预见性,过早优化是万恶之源
Skypemifan
2019-04-24 15:18:37 +08:00
COW 是指写时拷贝复制吗??

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/558026

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX