简体   繁体   中英

Using the copy-and-swap idiom, how does the destructor of the copied object not deallocate pointed to memory?

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?

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() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM