0

I was reading the following question:

What is the copy-and-swap idiom?

I was under the impression that when an object is passed by value, it's pointers and values are copied, but the memory pointed to by the passed object's pointers is not copied. So when overloading the assignment operator like such from the linked to example:

#include <algorithm> // std::copy
#include <cstddef> // std::size_t

class dumb_array
{
public:
    // (default) constructor
    dumb_array(std::size_t size = 0)
        : mSize(size),
          mArray(mSize ? new int[mSize]() : 0)
    {
    }

    // copy-constructor
    dumb_array(const dumb_array& other) 
        : mSize(other.mSize),
          mArray(mSize ? new int[mSize] : 0),
    {
        // note that this is non-throwing, because of the data
        // types being used; more attention to detail with regards
        // to exceptions must be given in a more general case, however
        std::copy(other.mArray, other.mArray + mSize, mArray);
    }

    // destructor
    ~dumb_array()
    {
        delete [] mArray;
    }

    friend void swap(dumb_array& first, dumb_array& second) // nothrow
    {
        // enable ADL (not necessary in our case, but good practice)
        using std::swap; 

        // by swapping the members of two classes,
        // the two classes are effectively swapped
        swap(first.mSize, second.mSize); 
        swap(first.mArray, second.mArray);
    }

    dumb_array& operator=(dumb_array other) // (1)
    {
        swap(*this, other); // (2)

        return *this;
    } 

private:
    std::size_t mSize;
    int* mArray;
};

... how does the destructor of the copied object not eliminate the pointed to resource, mArray? Doesn't the object on which the assignment is being done now have a copied mArray pointer to potentially deallocated memory? Does the line swap(first.mArray, second.mArray); allocate new memory and copy the contents of the previous array?

Community
  • 1
  • 1
Nathan Lutterman
  • 1,855
  • 4
  • 23
  • 38
  • How was `dumb_array::dumb_array(const dumb_array&)` implemented? – timrau Feb 25 '15 at 02:18
  • I'll edit in the entire example class. Are you implying that the copy constructor is called when the assignment operator is used? I don't see where it would be used in the swap function or in the overloaded assignment function. – Nathan Lutterman Feb 25 '15 at 02:19
  • Yes. Now put it in a self-answer instead of an edit. (or remove the question). – Deduplicator Feb 25 '15 at 02:28
  • You edited to answer your own question. `other` is a (deep) copy since it was passed by value and used your correctly-implemented copy-constructor. When `operator=` returns, `other` is then destructed, which will free the resources formerly held by `*this`. There's never two objects sharing the same resource. – M.M Feb 25 '15 at 02:29

1 Answers1

1

As your copy constructor implemented,

dumb_array(const dumb_array& other) 
        : mSize(other.mSize),
          mArray(mSize ? new int[mSize] : 0),

the mArray inside dumb_array was deeply copied. Not just copied the pointer, but created a brand new array and filled with copies of content by std::copy().

Thus, when operator=(dumb_array other) is executed, this->mArray and other.mArray (which is a copy since the parameter is an object instead of a reference) are two different arrays. After the swap(), other.mArray holds the pointer originally held by this->mArray. And when operator=() returns, other.mArray could just be deleted by ~dumb_array().

timrau
  • 22,578
  • 4
  • 51
  • 64