在自我分配期间,复制和交换习语是如何工作的?

Ash*_*sha 4 c++ exception-handling

我正在阅读优秀的复制和交换成语问题和答案.但有一件事我没有得到:如果自我分配,它如何运作?other示例中提到的对象是否会释放分配给的内存mArray?因此,自我分配的对象最终是否会出现无效指针?

Mar*_*ork 6

但有一件事我没有得到它如何在自我分配的情况下工作?

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

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;
}
Run Code Online (Sandbox Code Playgroud)

通常你实现上面的:

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;
}
Run Code Online (Sandbox Code Playgroud)

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

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

因此,自我分配的对象最终是否会出现无效指针?

没有.

  • @Hummingbird:在有自我分配的情况下,有更多的开销.**但**自我分配极为罕见(实际代码中很少).如果你看看相反的方式.如果您正在优化自我分配的代码,那么您正在使代码正常化以进行正常操作.现在,正常操作更加普遍,它实际上可以产生可衡量的差异(人们已经完成了这个时间).我愿意在经常发生的情况下为极佳代码极少发生的情况支付额外费用. (2认同)