Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
192 / 166 / 82
Регистрация: 01.07.2016
Сообщений: 943

Return для перегруженных операторов

10.12.2017, 23:43. Показов 1431. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class coord
{
    int x;
    int y;
public:
    coord(const int i = 0, const int j = 0) { x = i, y = j; }
    coord operator=(const coord&);
    void get_xy(int &i, int &j) { i = x; j = y; }
};
 
coord coord::operator=(const coord &obj)
{
    return coord(this->x = obj.x, this->y = obj.y);
}
Что означает вот эта строчка "return coord(this->x = obj.x, this->y = obj.y);" не совсем понимаю её смысл и почему если
тип возвращаемого значения сделать ссылочной это строчка будет работать криво(в результате в x и y появляется какой- то мусор).
C++
1
2
3
4
coord& coord::operator=(const coord &obj)
{
    return coord(this->x = obj.x, this->y = obj.y);
}
вот так криво работает.


А если написать так то всё работает
C++
1
2
3
4
5
6
coord& coord::operator=(const coord &obj)
{
    this->x = obj.x; 
    this->y = obj.y;
    return *this;
}
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
10.12.2017, 23:43
Ответы с готовыми решениями:

Что такое "перегрузка операторов"? Каковы принципы работы перегруженных операторов и назначение указателя this
Добрый день . Помогите понять принцип работы перегрузки операторов. объясните пожалуйста в зависимости от чего зависит агрумент при...

Импорт из dll перегруженных операторов
Здравствуйте, уважаемые программисты! По заданию необходимо при явном подключении dll импортировать класс. С обычными методами все...

Наследование перегруженных операторов ввода/вывода
Нужно наследовать операторы ввода вывода и добавить еще одно поле Условно есть программа: ... class 2D {

13
Модератор
Эксперт С++
 Аватар для zss
13773 / 10966 / 6491
Регистрация: 18.12.2011
Сообщений: 29,244
11.12.2017, 07:29
По ссылке нельзя возвращать объект, который будет уничтожен при выходе из функции.
2
192 / 166 / 82
Регистрация: 01.07.2016
Сообщений: 943
11.12.2017, 10:14  [ТС]
А почему так работает? Здесь я тоже возвращаю объект по ссылке
C++
1
2
3
4
5
6
coord& coord::operator=(const coord &obj)
{
    this->x = obj.x; 
    this->y = obj.y;
    return *this;
}
0
techpriest
 Аватар для Mirmik
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
11.12.2017, 11:26
Каждый объект имеет свой срок жизни.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//Здесь возврат ссылки валиден, потому что объект i передается в функции func снаружи, и на момент ее завершения //продолжит быть.
int& func(int& i) {
    return i;
} 
 
//Также валидно, потому что глобальный объект не будет уничтожен по выходу из функции.
int i;
int& func() {
    return i;
}
 
//И вновь можно, т.к. статическая переменная существует глобально.
int& func() {
    static int i;
    return i;
}
 
//А вот это невалидно, т.к. под переменную i память будет выделена из стэка в начале работы функции, а по завершении ее память будет освобождена.
int& func() {
    int i;
    return i;
}
Добавлено через 2 минуты
П.С. немного некорректно говорить "возвращаю объект по ссылке". Да, есть такая терминология, но она несколько путает. Объект никуда, на самом деле, не передается. Правильно сказать "возвращаю ссылку на объект".
1
192 / 166 / 82
Регистрация: 01.07.2016
Сообщений: 943
11.12.2017, 11:59  [ТС]
Спасибо огромное за ваши ответы! Я знаю что для вас это элементарно просто и логично но я не могу уловить суть данной функции.
C++
1
2
3
4
coord& coord::operator=(const coord &obj)
{
    return coord(this->x = obj.x, this->y = obj.y);
}
И чем она отличается от этой функции
C++
1
2
3
4
5
6
coord& coord::operator=(const coord &obj)
{
    this->x = obj.x; 
    this->y = obj.y;
    return *this;
}
Потестил первую функцию, оказалось что она не работает для такой формы записи (object1 = object2 = object3), а работает только для такой (object1 = object2). Но если сделать возвращаемое значение функции не как ссылку на объект то всё работает.
То есть так:
C++
1
2
3
4
coord coord::operator=(const coord &obj)
{
    return coord(this->x = obj.x, this->y = obj.y);
}
0
techpriest
 Аватар для Mirmik
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
11.12.2017, 12:04
Лучший ответ Сообщение было отмечено no swear как решение

Решение

C++
1
coord(this->x = obj.x, this->y = obj.y);
Это конструктор. Он создает объект, который будет уничтожен в момент выхода из функции.

C++
1
2
3
4
coord coord::operator=(const coord &obj)
{
    return coord(this->x = obj.x, this->y = obj.y);
}
Здесь вы требуете у компилятора вернуть в вызывающую функцию копию уничтожаемого объекта.

C++
1
2
3
4
coord& coord::operator=(const coord &obj)
{
    return coord(this->x = obj.x, this->y = obj.y);
}
А здесь вы требуете у компилятора вернуть ссылку на уничтожаемый объект. (которая сразу же становится невалидной)
1
192 / 166 / 82
Регистрация: 01.07.2016
Сообщений: 943
11.12.2017, 12:05  [ТС]
Я так полагаю функция
C++
1
2
3
4
coord& coord::operator=(const coord &obj)
{
    return coord(this->x = obj.x, this->y = obj.y);
}
перед тем как вернуть значение(ссылку на объект) генерирует временный объект на которую и будет ссылаться но по завершению этой функции объект выходит из зоны видимости и уничтожается а тем временем функция ссылается на этот уже уничтоженный объект.
Исправьте если я где-то ошибся, просто мысли в слух


Хотел до вас написать сообщение
0
techpriest
 Аватар для Mirmik
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
11.12.2017, 12:07
Лучший ответ Сообщение было отмечено no swear как решение

Решение

Для справки.

Компилятор имеет специальную оптимизацию для конструкций вида
C++
1
2
3
4
coord coord::operator=(const coord &obj)
{
    return coord(this->x = obj.x, this->y = obj.y);
}
Я сказал, что функция вернет копию объекта, но на самом деле, благодаря оптимизации компилятора, функция будет упрощена, и программа будет сразу же конструировать объект в том месте, куда он должен быть копирован. Поэтому накладных расходов на операцию копирования не будет.
1
192 / 166 / 82
Регистрация: 01.07.2016
Сообщений: 943
11.12.2017, 15:47  [ТС]
Значит такая запись
C++
1
2
3
4
5
6
7
coord& coord::operator+(const coord &obj)
{
    coord tmp;
    tmp.x = this->x + obj.x;
    tmp.y = this->y + obj.y;
    return tmp;
}
будет эквивалентна такой
C++
1
2
3
4
coord& coord::operator+(const coord &obj)
{
    return coord(this->x + obj.x, this->y + obj.y);
}
То есть оба ссылаются на локальные данные которые потом будут уничтожены
0
techpriest
 Аватар для Mirmik
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
11.12.2017, 15:53
Да. Верно.
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9006 / 4707 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
11.12.2017, 17:25
Лучший ответ Сообщение было отмечено no swear как решение

Решение

no swear, оператор приравнивания обычно возвращает ссылку на себя (*this).
Это потому, что иначе нельзя будет написать: a=b=c=d;
Ну и конечно, - проверка на само-приравнивание. В данном примере с хабра (лень было самому писать ) данная проверка смысла не имеет. Она нужна для классов, выделяющих память в куче (обязательно напишите м поюзайте такой пример). Дело в том, что в случае отсутствия такой проверки, объект сначала освободит память, а потом самоприравнияется. То есть, приплыли.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Integer
{
private:
    int value;
public:
    Integer(int i): value(i) 
    {}
 
    Integer& operator=(const Integer& right) {
        //проверка на самоприсваивание
        if (this == &right) {
            return *this;
        }
        value = right.value;
        return *this;
    }
};
1
192 / 166 / 82
Регистрация: 01.07.2016
Сообщений: 943
11.12.2017, 18:57  [ТС]
IGPIGP, Спасибо что ответили. Мне вот всё равно не даёт покоя один вопрос на который не могу найти ответ, почему если написать так:
C++
1
2
3
4
coord& coord::operator=(const coord &obj) // Ссылка на объект
{
    return coord(this->x = obj.x, this->y = obj.y);
}
то программа работает только для такого примера object1 = object2.

А если без ссылки на объект
C++
1
2
3
4
coord coord::operator=(const coord &obj)
{
    return coord(this->x = obj.x, this->y = obj.y);
}
то программа будет работать и на таких примерах object1 = object2 = object3 = object4.

Есть ли "мощное" объяснение этому явлению?

Добавлено через 5 минут
Ой ИЗВИНИТЕ я уже получил ответ выше!
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9006 / 4707 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
11.12.2017, 19:14
Цитата Сообщение от no swear Посмотреть сообщение
почему если написать так:
Это ошибка. Нельзя вернуть локальный объект в виде неконстантной ссылки.
Налицо 2 проблемы.
1. Повторите ссылки. Особенно возврат по ссылке.
2. Операторы класса, как функции члены.
Во втором пункте обратите внимание на то, что что бинарный оператор - член вызывается на экземпляре. Например, оператор присваивания:
C++
1
a=b;
фактически это
C++
1
a.operator=(b);
поняв это Вы сразу поймёте, что присваивание присваивает объект на котором вызвано, объекту с которым (в виде параметра) вызвано. Тогда не будет вопроса : - "А что же мне вернуть?", так как по сути выбор небогат.

Добавлено через 52 секунды
Цитата Сообщение от no swear Посмотреть сообщение
Ой ИЗВИНИТЕ я уже получил ответ выше!
Поздно.
Цитата Сообщение от no swear Посмотреть сообщение
то программа будет работать и на таких примерах object1 = object2 = object3 = object4.
Она будет создавать тучу копий.
1
192 / 166 / 82
Регистрация: 01.07.2016
Сообщений: 943
11.12.2017, 19:20  [ТС]
Спасибо огромное Mirmik, IGPIGP, zss за то что помогли мне понять эту тему
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
11.12.2017, 19:20
Помогаю со студенческими работами здесь

В чем разница между return и return false/true
Привет всем. Вот подскажите плиз) return; return false; return true; расскажите пожалуйста об етих операторах.. чем они...

Как сделать так, что если файл существует return true, если нет - return false
Здравствуйте, я новичок в программировании. Мой вопрос очень прост: как сделать так, что если файл существует return true если нет return...

Return возвращает условие. Для чего?
Не перестаю удивляться языку с++... Встретил сегодня такую строчку в программе if(Fun::fff(argv)) { cout << "Correct "...

Создание перегруженных функций
Написать перегруженную функцию, которая возвращает сумму двух целых чисел, трех целых чисел, двух слов

Реализация перегруженных функций
Нужна помощь по реализации перегруженных функций: int func (int * arr, int length, int number); int func (char * str, char ch); ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru