Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I need to delete resources when using copy-assign operator?

Code like this from one of my books for example:

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

HasPtr& HasPtr::operator=(const HasPtr &rhs){
    auto newp = new string(*rhs.ps); // copy the underlying string
    delete ps; // free the old memory
    ps = newp; // copy data from rhs into this object
    i = rhs.i;
    return *this; // return this object
}

Seems like the inside of the operator= could just be:

*ps = *rhs.ps
i = rhs.i
return *this;

With no need to delete the pointer first, seems redundant to do so. It did mention it is written in a way to leave the object in a suitable state should an exception occur but didn't divulge past that, but I don't see what exception could occur that even my alternative wouldn't handle. Why is there a need to delete the object first before assigning?

like image 630
AntiElephant Avatar asked Aug 27 '15 23:08

AntiElephant


People also ask

Why is copy assignment operator implicitly deleted?

A implicitly-declared copy assignment operator for class T is defined as deleted if any of the following is true: T has a user-declared move constructor; T has a user-declared move assignment operator. Otherwise, it is defined as defaulted.

Why do we delete the copy constructor?

When to delete copy constructor and assignment operator? Copy constructor (and assignment) should be defined when ever the implicitly generated one violates any class invariant. It should be defined as deleted when it cannot be written in a way that wouldn't have undesirable or surprising behaviour.

What is copy assignment operator?

A copy assignment operator of class T is a non-template non-static member function with the name operator= that takes exactly one parameter of type T, T&, const T&, volatile T&, or const volatile T&. For a type to be CopyAssignable, it must have a public copy assignment operator.


1 Answers

In this case, yes, that would be fine.

You're not leaking the dynamically-allocated string: you're re-using it.

like image 157
Lightness Races in Orbit Avatar answered Nov 14 '22 23:11

Lightness Races in Orbit