C++的 STL 普通容器为什么不做 Copy on write 的特性呢? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lhx2008
V2EX    问与答

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

  •  
  •   lhx2008 2019-04-23 19:03:59 +08:00 2389 次点击
    这是一个创建于 2442 天前的主题,其中的信息可能已经有所发展或是发生改变。
    初学 C++,理解不对请指教。

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

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

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

    这种问题得从 C++ 特色去考虑:COW 在修改时会 invalidate 掉 iterator 和 reference
    msg7086
        14
    msg7086  
       2019-04-23 22:01:09 +08:00
    因为 C 和 C++设计上就是允许你进行非常底层的操作的?
    是否 Copy 完全要看调用者的需求,而不是自动处理吧。
    lhx2008
        15
    lhx2008  
    OP
       2019-04-23 22:13:37 +08:00
    @msg7086 事实就是这么残酷,有些时候栈上分配的部分必须 Copy。
    一个方法是再用一个(智能)指针指向堆上内存,然后 Copy 的只是只用 Copy 指针,开销小一点。
    如果用 COW 的话,栈上也是要复制的(很少),只是堆上部分复不复制看情况。
    blinue
        16
    blinue  
       2019-04-23 22:22:22 +08:00 via Android   1
    c++11 引入的移动构造和赋值事实上足以解决很多问题,更何况 cow 的引入会使迭代器的复杂度倍增,原罪在于指针!
    lynskylate
        17
    lynskylate  
       2019-04-24 02:02:01 +08:00 via Android
    string 的 cow 已经被认为是失败的设计了
    iceheart
        18
    iceheart  
       2019-04-24 07:03:17 +08:00 via Android
    既然你有这需求了,为啥不自己实现一个这样的容器?
    做好了再拿出来去打标准委员会的脸。
    shihira
        19
    shihira  
       2019-04-24 09:19:38 +08:00 via Android
    如果在业务中有这样的需求,或者拷贝成为了性能瓶颈,你可以自己写一个这样的 vector 也不费什么劲,但这不适合作为标准库。标准库就是要逻辑清晰、行为有可预见性,过早优化是万恶之源
    Skypemifan
        20
    Skypemifan  
       2019-04-24 15:18:37 +08:00
    COW 是指写时拷贝复制吗??
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5161 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 31ms UTC 05:53 PVG 13:53 LAX 21:53 JFK 00:53
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86