mardi 29 décembre 2020

How's the Copy & Swap idiom really supposed to work, seriously! My code fails

I have been hearing about this, very advertised way of implementing an assign operator=() in C++.

Here's where it seems to fail,

A copy operator=() without Copy & Swap Idiom:

Data& operator=(const Data& rhs)
{
    if(this != &data)
    {
        _size = rhs.size();
        delete[] local_data;
        local_data = new char[_size];
        std::copy(rhs.data(), rhs.data() + rhs.size(), local_data);
    }
    return *this;
}
  1. Main.cpp with above (non-swap idiom) implementation called,

    int main(){
       Data a("Some data");
       auto ptr = a.data(); // Obtains a pointer to the original location
       a = Data("New data"); // When a is modified, this modification should effect the 'ptr'
       assert(ptr == a.data()); // Succeeds
       return 0;
     }
    

Same as above, except with Copy & Swap Idiom:

void swap(Data& rhs) noexcept
{
    std::swap(_size, rhs.size());
    std::swap(local_data, rhs.data());
}

Data& operator=(const Data& rhs)
{
    Data tmp(data);
    swap(data);
    return *this;
}

2: With swap idiom implementation:

int main(){
    Data a("Some data");
    auto ptr = a.data(); // Obtains a pointer to the original location
    a = Data("New data"); // When a is modified, this modification should effect the 'ptr' 
    assert(ptr == a.data()); // Fail
    return 0;
}

I observe, that there's clean up. But, is the clean and easy implementation of Copy & Swap Idiom supposed to fail here. And, I know that some runtime overhead does occur. But, generally, the Copy & Swap idiom seems a lot cleaner and better.

EDIT: I am aware of the self-assignment problem, and that this is supposed to help with that. Self-assignment is exceedingly rare in most programs, so an explicit check adds a small cost to every self-assignment even though the check is almost always false.

Sutter & Alexandrescu shows an assignment operator written in terms of a swap member. This is safe against self-assignment, exception-safe, and re-uses the copy constructor.

Aucun commentaire:

Enregistrer un commentaire