Зачем мне удалять ресурсы при использовании оператора копирования-назначения?

Код, например, из одной из моих книг, например:

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
}

Похоже, что внутри оператора = может быть просто:

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

Поскольку нет необходимости сначала удалять указатель, это кажется излишним. В нем упоминалось, что он написан таким образом, чтобы оставить объект в подходящем состоянии, если возникнет исключение, но не разглашал его, но я не вижу, какое исключение может произойти, даже моя альтернатива не будет обрабатываться. Почему перед удалением необходимо сначала удалить объект?

5

Решение

Это выглядит хорошо для меня.

И ты прав, std::string назначение уже предлагает строгую гарантию исключений, поэтому вы все равно оставите объект в исходном состоянии, если при копировании строки возникнет исключение.

Конечно, нет причин выделять std::string с new как это. Вы можете просто написать это вместо:

class HasNoPtr {
public:
HasNoPtr(const std::string& s): ps(s), i(0) { }
private:
std::string ps;
int i;
};
4

Другие решения

В этом случае, да, это было бы хорошо.

Вы не пропускаете динамически распределяемую строку: вы ее снова используете.

5

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector