2 / 2 / 0
Регистрация: 15.05.2019
Сообщений: 110
|
||||||||||||||||
1 | ||||||||||||||||
Классы и перегрузка операций28.08.2019, 11:40. Показов 1324. Ответов 20
Метки нет (Все метки)
Добрый день.
Изучаю в данный момент классы и перегрузку операций. Столкнулся с парой непонятных вещей, подскажите пожалуйста. 1)У Дейтлов в книге есть пример ими созданного класса Array, для работы с массивами целочисленных значений. Там есть перегруженная элемент-функция(метод) присваивания одного объекта класса другому(например integer1=integer2):
"Если бы проверка на самоприсваивание не производилась, то при самоприсваивании функция operator= перед своим завершением удаляла бы динамическую память, ассоциированную с объектом." В результате ptr указывал бы на память, которая была удалена." Но ведь при самоприсваивании, в вышеуказанной функции нигде не выделяется дин. память. Она же вроде выделяется, только если объекты разного размера, а в случае самоприсваивания размер одинаковый. Какая по их словам память удаляется при самоприсваивании, в данной функции(если бы не было проверки на самоприсваивание конечно)? 2)И второй вопрос: Есть у меня в классе Str(мною сделанном) функция присваивания одного объекта Str другому:
Если я использую вышеуказанную функцию, как написано, всё нормально присваивается. Но если я пытаюсь сделать возврат из функции не по ссылке а по значению, в string2 хранится мусор. Помогает только использование Конструктора копирования.
string2 лежит мусор? Ведь все действия по записи в него string1 были произведены в функции. Как на него возврат данных влияет?
0
|
28.08.2019, 11:40 | |
Ответы с готовыми решениями:
20
Классы. Перегрузка операций. С++ Классы перегрузка операций Перегрузка операций << и >> Перегрузка операций |
2 / 2 / 0
Регистрация: 15.05.2019
Сообщений: 110
|
|
28.08.2019, 11:56 [ТС] | 3 |
Извиняюсь, неправильно написал, в первом вопросе return вне if стоит. А вообще тут везде return используется только для каскадирования.
0
|
2 / 2 / 0
Регистрация: 15.05.2019
Сообщений: 110
|
|
28.08.2019, 12:49 [ТС] | 5 |
0
|
223 / 150 / 79
Регистрация: 14.03.2016
Сообщений: 459
|
|
28.08.2019, 13:15 | 7 |
Если вы не используете кастомный конструктор копирования, то все данные копируются дефолтным конструктором, т.е. вместо того, чтобы выделить новую память и скопировать туда значения, дефолтный конструктор просто копирует каждое поле из переданного объекта класса в свой. То есть, когда вы в функции копирования
operator= возвращаете объект по значению, создается временный объект, скопированный дефолтным конструктором (его sPtr указывает не на свой участок памяти под строку), и так как он временный, почти сразу после выхода из функции он будет уничтожен, будет вызван деструктор, который, полагаю, освободит память, занятой строкой.
1
|
9 / 7 / 2
Регистрация: 13.11.2014
Сообщений: 51
|
|
28.08.2019, 13:38 | 8 |
Присоединяюсь. Пост отражает всю суть происходящего.
Приложи весь код класса Str, чтоб развеять сомнения.
0
|
2 / 2 / 0
Регистрация: 15.05.2019
Сообщений: 110
|
||||||
28.08.2019, 14:15 [ТС] | 9 | |||||
Код ниже(с конструктором копии и возвратом по ссылке).
У меня не проблема с написанием, а именно больше с пониманием, почему происходит уничтожение(в данном случае str3), если убрать конструктор копии и возвращать объект по значению .После поста Cortas, вроде немного понял. То есть он получается, скопировал весь объект, а указатель оставил на область в дин памяти, где str3 находится?
0
|
2 / 2 / 0
Регистрация: 15.05.2019
Сообщений: 110
|
|
28.08.2019, 14:48 [ТС] | 11 |
Это понятно. Я имею ввиду тот момент,когда в operator= происходит возврат return *this.
0
|
"C with Classes"
|
|||||||||||
28.08.2019, 15:03 | 12 | ||||||||||
вызова деструктора str3 у тебя не происходит (если ты об этом). Деструкторы вызываются:
можно оптимизировать так:
кстати тут ошибка, размер массива должен быть константой: char tempPtr[256];
0
|
9 / 7 / 2
Регистрация: 13.11.2014
Сообщений: 51
|
||||||
28.08.2019, 15:03 | 13 | |||||
Да, примерно так.
Поясню немного, когда ты возвращаешь по значению, вот такой вариант:
Теперь про оптимизацию. Оба варианта работают 1) передача по ссылке 2) передача по значению, с определением конструктора Но смотри что во втором случае: ты выделяешь память, никак ее не используешь, а затем удаляешь - простым языком, куча лишних действий. Да, с++ стандарт не заставляет тебя возвращать именно ссылку в операторе присваивания, но принято вообще именно так. Для закрепления понимания советую обратиться к книгам Страуструпа, возможно я где-то соврал и будет не лишним ещё раз понять механизм вызова конструкторов, описанную создателем языка.
1
|
2 / 2 / 0
Регистрация: 15.05.2019
Сообщений: 110
|
|
28.08.2019, 15:22 [ТС] | 15 |
Странно, IDE все нормально отрабатывает.
Спасибо большое. Крайне доходчиво.
0
|
"C with Classes"
|
|
28.08.2019, 15:36 | 16 |
не стандартные расширения IDE, плодят не переносимый код.
Добавлено через 11 минут ты наверное уже созрел для понимания таких понятий как rvalue и lvalue , начинай гуглежку, но пока вот пара ссылок:http://rsdn.org/article/cpp/lvalue.xml https://habr.com/ru/post/348198/ и конечно же желаю тебе прекрасно повеселиться, когда дойдешь до xvalue, glvalue, prvalue.
0
|
2 / 2 / 0
Регистрация: 15.05.2019
Сообщений: 110
|
|
28.08.2019, 15:54 [ТС] | 17 |
Чуть чуть их уже понимаю Спасибо почитаю.
А по поводу размера массива, просто Дейтлы в new применяют такой вариант при создании массива в динамической памяти. Я на автомате и для статического так сделал)
0
|
2 / 2 / 0
Регистрация: 15.05.2019
Сообщений: 110
|
|
29.08.2019, 15:29 [ТС] | 18 |
Добрый день.
А вы не могли бы еще подсказать такой момент. Что возвращает функция если return не указан, а в прототипе и описании функции возвращаемое значение ostream&? Просто писал класс, забыл return output(синоним cout) в перегруженном << указать, а каскадный вывод cout<<class1<<class2 все равно сработал.
0
|
2 / 2 / 0
Регистрация: 15.05.2019
Сообщений: 110
|
|
29.08.2019, 15:58 [ТС] | 20 |
а как он объект class2 выводит? Компилятор сам додумывает что там по логике стоять должно?
0
|
29.08.2019, 15:58 | |
29.08.2019, 15:58 | |
Помогаю со студенческими работами здесь
20
Перегрузка операций Перегрузка операций << и >> Перегрузка операций Перегрузка операций Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |