Форум программистов, компьютерный форум CyberForum.ru

Как лучше возвращать значение из операции-функции - C++

Восстановить пароль Регистрация
 
frostua
0 / 0 / 0
Регистрация: 07.11.2011
Сообщений: 27
26.11.2011, 14:26     Как лучше возвращать значение из операции-функции #1
В следующем коде при перегрузке оператора '+' функция возвращает ссылку на временный объект
C++
1
Point&operator+(int d) и Point&operator+(int d,Point&Z)
но так же можно вернуть сам объект
C++
1
Point operator+(int d) и Point operator+(int d,Point&Z)
работает и так и так. Как лучше?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <iostream>
using namespace std;
 
// класс "точка"
class Point
{  
     // координаты точки
     int X;
     int Y;
 public:
 
     // конструктор
     Point(int iX,int iY){
         X=iX;
         Y=iY;
     }
 
     //показ на экран
     void Show(){
        cout<<"\n+++++++++++++++++++++\n";
        cout<<"X = "<<X<<"\tY = "<<Y;
        cout<<"\n+++++++++++++++++++++\n";
     }
 
     // перегруженный оператор +
     // метод класса для ситуации Point+int
     Point&operator+(int d){
         Point P(0,0);
         P.X=X+d;
         P.Y=Y+d;
         return P;
     }
     // функции доступа к 
     // privat-членам без них 
     // глобальная перегрузка невозможна
     int GetX() const{
         return X;
     }
     int GetY() const{
         return Y;
     }
     void SetX(int iX){
         X=iX;
     }
     void SetY(int iY){
         Y=iY;
     }  
};
 
 /*глобальная перегрузка
 для ситуации int + Point
 доступ к private-членам
 через специальные функции*/
Point&operator+(int d,Point&Z){
         Point P(0,0);
         P.SetX(d+Z.GetX());
         P.SetY(d+Z.GetY());
         return P;
}
 
void main() 
{ 
    // создание объекта
        Point A(3,2);
    A.Show();
 
    //оператор-метод +
    Point B=A+5;
    B.Show();
 
    //глобальный оператор 
    Point C=2+A;
    C.Show();
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.11.2011, 14:26     Как лучше возвращать значение из операции-функции
Посмотрите здесь:

C++ error C4716: Distance::getdist: должна возвращать значение
C++ Правильно возвращать значение из функции
.Написать функцию, которая будет возвращать значение y=ln(x)+x при входящем параметре x. Построить таблицу значений этой функции C++
Ошибка в функции (function: должна возвращать значение) C++
почему нельзя в операторе + возвращать оригинальное значение(по ссылке), а не копию. C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
26.11.2011, 14:33     Как лучше возвращать значение из операции-функции #2
frostua, разумеется, надо возвращать объект по значению. Вы ведь сами написали, что возвращается ссылка на локальный объект (т.е. на объект, который по выходе из функции перестанет существовать). Вдумайтесь в эту фразу и вы поймёте, что это может сулить.
Сыроежка
Заблокирован
26.11.2011, 14:41     Как лучше возвращать значение из операции-функции #3
frostua,

Оба варианта у вас плохие. Во-первых, операнд класса Point должен быть константной ссылкой. В противном случае вы не сможете ваш оператор использовать в некоторых конструкциях. Я не знаю, какие конструкторы есть у вашего класса Point, но будем считать что имеется конструктор по умолчанию. Тогда ваш код не должен компилироваться для следующего выражения

C++
1
10 + Point();
Второе замечание состоит в том, что ваш класс должен соответствовать семантики сложения фундаментальных типов, заключающаяся в том, что результат сложения является так называемое rvalue, то есть значение, которому ничего нельзя присвоить или как-то изменить. Например,

C++
1
2
3
int x = 10, y = 20;
 
( x + y )++;    // Ошбика. Нельзя изменить результат выражения
Поэтому корректный оператор должен выглядеть следующим образом

C++
1
2
const Point operator +( int a, const Point &b );
const Point operator +( int a ) const;
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
26.11.2011, 15:01     Как лучше возвращать значение из операции-функции #4
Цитата Сообщение от frostua Посмотреть сообщение
В следующем коде при перегрузке оператора '+' функция возвращает ссылку на временный объект
Дело не в том, что лучше. Временный объект можно возвращать только по значению, иначе нельзя, так как после возврата из функции он просто не будет существовать. То, что тебя работает - иллюзия. Первое же передача управления после возврата, но перед использованием другому процессу и ты рискуешь следующим совпадением:
1 в одной странице с этим данным не будет ни каких других твоих данных,
2 тот процесс тоже вызовет функцию.
Всё, та функция твой экс-стек испортит. А если результат функции участвует в выражении с ещё какой нибудь функцией, то значение может испортить даже данный процесс, достаточно, если в следующей версии поменяется порядок вызова функций и та другая будет вызываться после, а не до. Причём, отличие той версии может отстоять на тысячи строк.
mc_sh
0 / 0 / 0
Регистрация: 26.11.2011
Сообщений: 8
26.11.2011, 15:04     Как лучше возвращать значение из операции-функции #5
лудше всего сделать allocation и вернуть просто адресс.

с одной стороны обьект не "умрёт после завершения функции" а с другой ты возвращаеш ничего тяжёлого а просто его адресс
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
26.11.2011, 15:14     Как лучше возвращать значение из операции-функции #6
Цитата Сообщение от frostua Посмотреть сообщение
В следующем коде при перегрузке оператора '+' функция возвращает ссылку на временный объект
Дело не в том, что лучше. Временный объект можно возвращать только по значению, иначе нельзя, так как после возврата из функции он просто не будет существовать. То, что тебя работает - иллюзия. Первое же передача управления после возврата, но перед использованием другому процессу и ты рискуешь следующим совпадением:
1 в одной странице с этим данным не будет ни каких других твоих данных,
2 тот процесс тоже вызовет функцию.
Всё, та функция твой экс-стек испортит. А если результат функции участвует в выражении с ещё какой нибудь функцией, то значение может испортить даже данный процесс, достаточно, если в следующей версии поменяется порядок вызова функций и та другая будет вызываться после, а не до. Причём, в исходнике отличие той версии может отстоять на тысячи строк. Или даже ты ничего вообще не менял, просто ещё раз запустил компиляцию, например, для релиза вместо дебага, а компилятор принял иное решение. Так делать вообще нельзя.
frostua
0 / 0 / 0
Регистрация: 07.11.2011
Сообщений: 27
26.11.2011, 15:20  [ТС]     Как лучше возвращать значение из операции-функции #7
Цитата Сообщение от Сыроежка Посмотреть сообщение
frostua,

Оба варианта у вас плохие. Во-первых, операнд класса Point должен быть константной ссылкой. В противном случае вы не сможете ваш оператор использовать в некоторых конструкциях. Я не знаю, какие конструкторы есть у вашего класса Point, но будем считать что имеется конструктор по умолчанию. Тогда ваш код не должен компилироваться для следующего выражения

C++
1
10 + Point();
Второе замечание состоит в том, что ваш класс должен соответствовать семантики сложения фундаментальных типов, заключающаяся в том, что результат сложения является так называемое rvalue, то есть значение, которому ничего нельзя присвоить или как-то изменить. Например,

C++
1
2
3
int x = 10, y = 20;
 
( x + y )++;    // Ошбика. Нельзя изменить результат выражения
Поэтому корректный оператор должен выглядеть следующим образом

C++
1
2
const Point operator +( int a, const Point &b );
const Point operator +( int a ) const;
я привел полное описание класса, читайте до конца пост.
C++
1
10 + Point(10,10);
компилится нормально. В данном случае не нужно преобразование типа от int к Point

Ко второму замечанию - результат сложения получается объект класса Point, почему его нельзя поменять, если для него переопределена операция ++
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
26.11.2011, 15:31     Как лучше возвращать значение из операции-функции #8
Цитата Сообщение от frostua Посмотреть сообщение
10 + Point();
Число нельзя складывать с точкой.
Сыроежка
Заблокирован
26.11.2011, 15:41     Как лучше возвращать значение из операции-функции #9
Цитата Сообщение от frostua Посмотреть сообщение
я привел полное описание класса, читайте до конца пост.
C++
1
10 + Point(10,10);
компилится нормально. В данном случае не нужно преобразование типа от int к Point

Ко второму замечанию - результат сложения получается объект класса Point, почему его нельзя поменять, если для него переопределена операция ++
Я не точно выразился. Если у вас есть объявление

C++
1
const Point p( 10, 10 );
то у вас не будет компилироваться

C++
1
10 + p;
Что касается второго пункта, то я вам дал объяснение. Семантика вашего оператора сложения не должна отличаться от семантики оператора сложения для функдаментальных типов. Так делать нельзя

C++
1
2
]nt x = 10, y = 20;
( x + y )++;

Должен работать принцип максимальной предсказуемости. Пользователь рассчитывает на поведение, которое ему уже известно при работе с другими типами.
frostua
0 / 0 / 0
Регистрация: 07.11.2011
Сообщений: 27
26.11.2011, 15:46  [ТС]     Как лучше возвращать значение из операции-функции #10
-------------
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.11.2011, 15:55     Как лучше возвращать значение из операции-функции
Еще ссылки по теме:

Односвязные списки: нужно ли при выходе из функции возвращать голову? C++
Почему плохо возвращать указатель из функции? C++
Как правильно возвращать указатели из функции C++

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

Или воспользуйтесь поиском по форуму:
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
26.11.2011, 15:55     Как лучше возвращать значение из операции-функции #11
Цитата Сообщение от frostua Посмотреть сообщение
Ко второму замечанию - результат сложения получается объект класса Point, почему его нельзя поменять, если для него переопределена операция ++
Потому что эта операция изменения, а не сложения и применима только к переменным, а результат сложения - значение, то есть ближе к константам.
Yandex
Объявления
26.11.2011, 15:55     Как лучше возвращать значение из операции-функции
Ответ Создать тему
Опции темы

Текущее время: 13:35. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru