Другие языки программирования и технологии

Оператор присваивания C++

В учебнике написано:

"... объект catTwo уже существует вместе со своими переменными, для каждой из которых выделены определённые ячейки памяти. В случае присвоения объекту новых значений предварительно необходимо освободить эти ячейки памяти. Что произойдёт, если выполнить присвоение объекта catTwo самому себе:
catTwo=catTwo;
... присвоение объекта самому себе может произойти по ошибке.. .Если не предусмотреть поддержку такой ситуации, то оператор присваивания сначала очистит ячейки памяти объекта catTwo, а затем попытается присвоить объекту catTwo свои собственные значения, которых уже не будет и в помине". И дальше предлагается перегрузить оператор присваивания для класса, который будет сравнивать два адреса, чтобы избежать ошибки.

А почему тогда программа с таким кодом:

http://pastebin.com/sc76Jav4

у меня работает без ошибок?
Значит ли это, что прописывать в классе operator= всё-таки не обязательно?
Проблема с самоприсваиванием давно и легко решена:

#include <iostream>
#include <string>
using namespace std;
class user {
public:
    user(string _key, string _value) : key(_key), value(_value) { }
    user& operator=(const user&);
protected:
    string key;
    string value;
private:
    user() { }
};
int main() {
    user model("key", "value");
    model = model;
    cout value = rhs.value;
    return *this;
}

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

Вывод: стоит единожды в классе написать new и тут же следует явно реализовать конструктор копирования, деструктор и перегрузить оператор присваивания.
Vadim Rusu
Vadim Rusu
57 651
Лучший ответ
Дмитрий Гренц "Тем же грешит и оператор присваивания по умолчанию, который тупо копирует адреса указателей". - О, понятно.. . Спасибо!
Дмитрий Гренц Но почему всё-таки учебник обещает прекращение работы программы без решения, которое предложили и Вы, а у меня ничего не прекращает работать?
Я почему спрашиваю. Книжка-то старая. Но для меня она пока что первый и единственный источник информации. А вдруг теперь уже что-то изменилось, может, теперь адреса и без явного прописывания сравниваются или ещё что?. . А я и знать не буду)
Что за учебник? Нет кода, поэтому трудно что-то сказать. Вообще C/C++ отличается тем, что практически не делает неожиданных действий, вроде обнуления переменных, что, с одной стороны, ускоряет работу, с другой, приводит к UB. Оператор присваивания по умолчанию ничего не очищает, это точно.
А обязательно ли перегружать? Конечно, не обязательно, надо смотреть по ситуации. Если есть члены-указатели - лучше все-таки перегрузить, во избежение утечек памяти.
Дмитрий Гренц Спасибо большое за ответ.

Учебник Либерти "Освой ...за 21 день". Конкретно к этому тексту никакого кода и нет.
А что такое UB?