Is it easier to implement the copy assignment operator?

In C ++ Primer 5th, 13.2.1 Class That Act Like Values, create a class that acts like a value, which means that each object has its own copy of the resource that the class manages. The class below, It is a very simple class, it just holds a pointer to a string, and the int, member function is just the default constructor and copy control.

class HasPtr{
    public:
    HasPtr(const std::string &s = std::string()) :ps(new std::string(s)), i(0){}
    HasPtr(const HasPtr &p) :ps(new std::string(*p.ps)), i(p.i){}
    HasPtr &operator=(const HasPtr &rhs);
    ~HasPtr(){ delete ps; }
    private:
        std::string *ps;
        int i;
};

      

Below is the implementation of the operator = given by the book

HasPtr &HasPtr::operator=(const HasPtr &rhs){
    auto newp = new std::string(*rhs.ps);
    delete ps;
    ps = newp;
    i = *rhs.i;
    return *this;
}

      

This is good, but I think we can use the following tool, which can avoid deleting the pointer and allocate new memory.

HasPtr &HasPtr::operator=(const HasPtr &rhs){
    *ps = *rhs.ps;
    i = rhs.i;
    return *this;
}

      

I am testing my code, even self-awareness. However, are there any problems with this code?

+3


source to share


2 answers


No, there is no problem in your code.

*ps

      

itself is a value type, so you can assign it directly. If you are making changes to improve your code, you can go ahead and change ps to std :: string instead of std :: string *. Then you can eliminate the need for new ones and remove from the HasPtr class.



If a

*ps

      

instead were a raw memory pointer managed by the HasPtr class, you would have to write code like in the example from the book.

+3


source


In your original example, you copied the contents of * ps for yourself, which is ok. However, as the comment told you, this may not always be the case.

As for other solutions, here is one (maybe something like this will be explained later in your book):

#include <algorithm>
//...
HasPtr &HasPtr::operator=(const HasPtr &rhs)
{
    HasPtr temp(rhs);
    std::swap(ps, temp.ps);
    std::swap(i, temp.i);
    return *this;
}

      



This is an idiom copy/swap

. A temporary creation is created from rhs

, and internal temporary items are replaced with members this

. The temporary ones die at the end, taking with them the old values.

Note that there is no explicit memory allocation as you rely on the copy constructor to create a temporary copy initially. This means that this method requires a working copy constructor and a working destructor. Once you have everything, the assignment operator is very simple if done like this, because there is no real coding for "grunt work" - the copy constructor will handle it.

So it's easier than the book version? Depending on how you look at it - copy / swap can be used in almost every situation where you basically need to start with working implementations of two of the three functions described in "rule 3", namely the copy constructor and destructor. The assignment operator is just fine to ride, taking advantage of the other two functions, and also does simple swaps.

0


source







All Articles