lhx2008
V2EX  ›  问与答

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

  •  
  •   lhx2008 · Apr 23, 2019 · 2607 views
    This topic created in 2601 days ago, the information mentioned may be changed or developed.
    初学 C++,理解不对请指教。

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

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

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

    这种问题得从 C++ 特色去考虑:COW 在修改时会 invalidate 掉 iterator 和 reference
    msg7086
        14
    msg7086  
       Apr 23, 2019
    因为 C 和 C++设计上就是允许你进行非常底层的操作的?
    是否 Copy 完全要看调用者的需求,而不是自动处理吧。
    lhx2008
        15
    lhx2008  
    OP
       Apr 23, 2019
    @msg7086 事实就是这么残酷,有些时候栈上分配的部分必须 Copy。
    一个方法是再用一个(智能)指针指向堆上内存,然后 Copy 的只是只用 Copy 指针,开销小一点。
    如果用 COW 的话,栈上也是要复制的(很少),只是堆上部分复不复制看情况。
    blinue
        16
    blinue  
       Apr 23, 2019 via Android   ❤️ 1
    c++11 引入的移动构造和赋值事实上足以解决很多问题,更何况 cow 的引入会使迭代器的复杂度倍增,原罪在于指针!
    lynskylate
        17
    lynskylate  
       Apr 24, 2019 via Android
    string 的 cow 已经被认为是失败的设计了
    iceheart
        18
    iceheart  
       Apr 24, 2019 via Android
    既然你有这需求了,为啥不自己实现一个这样的容器?
    做好了再拿出来去打标准委员会的脸。
    shihira
        19
    shihira  
       Apr 24, 2019 via Android
    如果在业务中有这样的需求,或者拷贝成为了性能瓶颈,你可以自己写一个这样的 vector 也不费什么劲,但这不适合作为标准库。标准库就是要逻辑清晰、行为有可预见性,过早优化是万恶之源
    Skypemifan
        20
    Skypemifan  
       Apr 24, 2019
    COW 是指写时拷贝复制吗??
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2832 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 61ms · UTC 10:11 · PVG 18:11 · LAX 03:11 · JFK 06:11
    ♥ Do have faith in what you're doing.