自我指派保護

在編寫複製賦值運算子時,非常重要的是它能夠在自我賦值的情況下工作。也就是說,它必須允許這樣:

SomeType t = ...;
t = t;

自我分配通常不會以這種顯而易見的方式發生。它通常通過各種程式碼系統的迂迴路徑發生,其中賦值的位置只有兩個 Person 指標或引用,並且不知道它們是同一個物件。

你編寫的任何複製賦值運算子都必須考慮到這一點。

這樣做的典型方法是將所有賦值邏輯包裝在如下的條件中:

SomeType &operator=(const SomeType &other)
{
    if(this != &other)
    {
        //Do assignment logic.
    }
    return *this;
}

注意: 考慮自我分配並確保程式碼在發生時正常執行很重要。然而,自我分配是非常罕見的,並且優化以防止它可能實際上使正常情況變得悲觀。由於正常情況更為常見,因此對自我分配感到悲觀可能會降低程式碼效率(因此請小心使用它)。

例如,實現賦值運算子的常規技術是 copy and swap idiom。這種技術的正常實現並不打算測試自我分配(即使由於複製而自我分配也很昂貴)。原因是正常情況的悲觀化已被證明成本更高(因為它經常發生)。

Version >= C++ 11

還必須保護移動賦值運算子以防止自我賦值。然而,許多這樣的運算子的邏輯基於 std::swap,它可以處理從/到相同記憶體的交換。因此,如果你的移動分配邏輯只是一系列交換操作,那麼你不需要自我分配保護。

如果不是這種情況,你必須採取與上述類似的措施。