【问题标题】:How does the copy-and-swap idiom work during self-assignment?在自我分配期间,复制和交换习语如何工作?
【发布时间】:2011-04-26 07:57:06
【问题描述】:

我正在阅读优秀的copy-and-swap idiom 问题和答案。但是我没有得到一件事:在自我分配的情况下它是如何工作的?示例中提到的对象other 不会释放分配给mArray 的内存吗?那么被自赋值的对象不会有一个无效的指针吗?

【问题讨论】:

    标签: c++ exception-handling


    【解决方案1】:

    但是我不明白的一件事是在自我分配的情况下它是如何工作的?

    让我们看一个简单的案例:

    class Container
    {
        int*   mArray;
    };
    
    // Copy and swap
    Container& operator=(Container const& rhs)
    {
        Container   other(rhs);  // You make a copy of the rhs.
                                 // This means you have done a deep copy of mArray
    
        other.swap(*this);       // This swaps the mArray pointer.
                                 // So if rhs and *this are the same object it
                                 // does not matter because other and *this are
                                 // definitely not the same object.
    
        return *this;
    }
    

    通常您将上述实现为:

    Container& operator=(Container other)
                           // ^^^^^^^^     Notice here the lack of `const &`
                           //              This means it is a pass by value parameter.
                           //              The copy was made implicitly as the parameter was passed. 
    {
        other.swap(*this);
    
        return *this;
    }
    

    示例中提到的其他对象不会释放分配给 mArray 的内存吗?

    该副本制作 mArray 的深层副本。
    然后我们用 this.mArray 交换。当其他超出范围时,它会释放 mArray(如预期的那样),但这是它自己的唯一副本,因为我们在执行复制操作时进行了深层复制。

    那么,自分配的对象最终不会有一个无效的指针吗?

    没有。

    【讨论】:

    • 哎呀..我错过了复制ctor中的深层副本..感谢您的解释。
    • 旧帖子,但我仍然有同样的疑问.. 与if (this == &other) return *this; 相比,在使用复制交换习语时进行自我分配的开销是不是太大了?
    • @Hummingbird:在有自分配的情况下会有更多的开销。 BUT 自赋值极为罕见(在实际代码中非常小)。如果你反过来看。如果您正在优化代码以进行自分配,那么您正在对正常操作的代码感到失望。现在,正常操作是如此普遍,以至于它实际上可以产生可衡量的差异(人们已经做到了这一点)。我愿意在极少发生的情况下支付额外的成本,以在非常频繁发生的情况下获得最佳代码。
    猜你喜欢
    • 1970-01-01
    • 2020-05-27
    • 2011-10-28
    • 2023-03-23
    • 2021-07-09
    • 2011-11-22
    • 2011-01-09
    • 2015-04-26
    • 2014-06-23
    相关资源
    最近更新 更多