В учебнике написано:
"... объект catTwo уже существует вместе со своими переменными, для каждой из которых выделены определённые ячейки памяти. В случае присвоения объекту новых значений предварительно необходимо освободить эти ячейки памяти. Что произойдёт, если выполнить присвоение объекта catTwo самому себе:
catTwo=catTwo;
... присвоение объекта самому себе может произойти по ошибке.. .Если не предусмотреть поддержку такой ситуации, то оператор присваивания сначала очистит ячейки памяти объекта catTwo, а затем попытается присвоить объекту catTwo свои собственные значения, которых уже не будет и в помине". И дальше предлагается перегрузить оператор присваивания для класса, который будет сравнивать два адреса, чтобы избежать ошибки.
А почему тогда программа с таким кодом:
http://pastebin.com/sc76Jav4
у меня работает без ошибок?
Значит ли это, что прописывать в классе operator= всё-таки не обязательно?
Другие языки программирования и технологии
Оператор присваивания C++
Проблема с самоприсваиванием давно и легко решена:
#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 и тут же следует явно реализовать конструктор копирования, деструктор и перегрузить оператор присваивания.
#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 и тут же следует явно реализовать конструктор копирования, деструктор и перегрузить оператор присваивания.
Что за учебник? Нет кода, поэтому трудно что-то сказать. Вообще C/C++ отличается тем, что практически не делает неожиданных действий, вроде обнуления переменных, что, с одной стороны, ускоряет работу, с другой, приводит к UB. Оператор присваивания по умолчанию ничего не очищает, это точно.
А обязательно ли перегружать? Конечно, не обязательно, надо смотреть по ситуации. Если есть члены-указатели - лучше все-таки перегрузить, во избежение утечек памяти.
А обязательно ли перегружать? Конечно, не обязательно, надо смотреть по ситуации. Если есть члены-указатели - лучше все-таки перегрузить, во избежение утечек памяти.
Дмитрий Гренц
Спасибо большое за ответ.
Учебник Либерти "Освой ...за 21 день". Конкретно к этому тексту никакого кода и нет.
А что такое UB?
Учебник Либерти "Освой ...за 21 день". Конкретно к этому тексту никакого кода и нет.
А что такое UB?
Похожие вопросы
- Как перегружать оператор присваивания?
- Помогите с переопределением операторов в C++
- Перегрузка оператора в C++
- оператор if C#
- программа с помощью оператора case (C++)
- Задание по оператору выбора C++
- Присваивание номера адреса. C++
- Оператор ввода в C#
- Как осуществить операцию сложения в с++ без операции присваивания ? int a=5; int b=6; int c=a+b; ( без "= ")
- Ненужное присваивание в условии. С++
Я почему спрашиваю. Книжка-то старая. Но для меня она пока что первый и единственный источник информации. А вдруг теперь уже что-то изменилось, может, теперь адреса и без явного прописывания сравниваются или ещё что?. . А я и знать не буду)