С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.85/13: Рейтинг темы: голосов - 13, средняя оценка - 4.85
0 / 0 / 0
Регистрация: 07.11.2011
Сообщений: 27
1

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

26.11.2011, 14:26. Показов 2321. Ответов 10
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
В следующем коде при перегрузке оператора '+' функция возвращает ссылку на временный объект
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();
}
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
26.11.2011, 14:26
Ответы с готовыми решениями:

Как дать понять функции в delphi куда возвращать значение
Скажите ,как передать данные из файла на выход данной функции? function...

Правильно возвращать значение из функции
Есть недопонимание в этом вопросе. Понимаю, что локальные переменные вернуть нельзя, так как они...

Ошибка в функции (function: должна возвращать значение)
ребят, компилятор выдает error C4716: function: должна возвращать значение что это значит? как с...

В ООП все функции должны возвращать значение?
Может ли функция работать, не возвращая значений? Думаю, с глобальными переменными может... А как...

10
Эксперт С++
5057 / 3117 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
26.11.2011, 14:33 2
frostua, разумеется, надо возвращать объект по значению. Вы ведь сами написали, что возвращается ссылка на локальный объект (т.е. на объект, который по выходе из функции перестанет существовать). Вдумайтесь в эту фразу и вы поймёте, что это может сулить.
1
Заблокирован
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;
0
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
26.11.2011, 15:01 4
Цитата Сообщение от frostua Посмотреть сообщение
В следующем коде при перегрузке оператора '+' функция возвращает ссылку на временный объект
Дело не в том, что лучше. Временный объект можно возвращать только по значению, иначе нельзя, так как после возврата из функции он просто не будет существовать. То, что тебя работает - иллюзия. Первое же передача управления после возврата, но перед использованием другому процессу и ты рискуешь следующим совпадением:
1 в одной странице с этим данным не будет ни каких других твоих данных,
2 тот процесс тоже вызовет функцию.
Всё, та функция твой экс-стек испортит. А если результат функции участвует в выражении с ещё какой нибудь функцией, то значение может испортить даже данный процесс, достаточно, если в следующей версии поменяется порядок вызова функций и та другая будет вызываться после, а не до. Причём, отличие той версии может отстоять на тысячи строк.
0
0 / 0 / 0
Регистрация: 26.11.2011
Сообщений: 8
26.11.2011, 15:04 5
лудше всего сделать allocation и вернуть просто адресс.

с одной стороны обьект не "умрёт после завершения функции" а с другой ты возвращаеш ничего тяжёлого а просто его адресс
0
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
26.11.2011, 15:14 6
Цитата Сообщение от frostua Посмотреть сообщение
В следующем коде при перегрузке оператора '+' функция возвращает ссылку на временный объект
Дело не в том, что лучше. Временный объект можно возвращать только по значению, иначе нельзя, так как после возврата из функции он просто не будет существовать. То, что тебя работает - иллюзия. Первое же передача управления после возврата, но перед использованием другому процессу и ты рискуешь следующим совпадением:
1 в одной странице с этим данным не будет ни каких других твоих данных,
2 тот процесс тоже вызовет функцию.
Всё, та функция твой экс-стек испортит. А если результат функции участвует в выражении с ещё какой нибудь функцией, то значение может испортить даже данный процесс, достаточно, если в следующей версии поменяется порядок вызова функций и та другая будет вызываться после, а не до. Причём, в исходнике отличие той версии может отстоять на тысячи строк. Или даже ты ничего вообще не менял, просто ещё раз запустил компиляцию, например, для релиза вместо дебага, а компилятор принял иное решение. Так делать вообще нельзя.
1
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, почему его нельзя поменять, если для него переопределена операция ++
0
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
26.11.2011, 15:31 8
Цитата Сообщение от frostua Посмотреть сообщение
10 + Point();
Число нельзя складывать с точкой.
0
Заблокирован
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 )++;

Должен работать принцип максимальной предсказуемости. Пользователь рассчитывает на поведение, которое ему уже известно при работе с другими типами.
1
0 / 0 / 0
Регистрация: 07.11.2011
Сообщений: 27
26.11.2011, 15:46  [ТС] 10
-------------
0
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
26.11.2011, 15:55 11
Цитата Сообщение от frostua Посмотреть сообщение
Ко второму замечанию - результат сложения получается объект класса Point, почему его нельзя поменять, если для него переопределена операция ++
Потому что эта операция изменения, а не сложения и применима только к переменным, а результат сложения - значение, то есть ближе к константам.
0
26.11.2011, 15:55
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
26.11.2011, 15:55
Помогаю со студенческими работами здесь

Подскажите пример описания функции, которая будет возвращать значение
Пожалуйста, подскажите пример описания функции, которая будет возвращать значение (хочу понять...

Как лучше получить значение переменой в функции?
Мне в функцию через CALL приходит информация в двух видах: name и path\path\name Нужно...

Как передавать в аргумент функции массив, и можно ли возвращать его из функции?
привет друзья! можно ли в VB 6.0 передавать в аргумент функции массив и можно ли возвращать его...

Как возвращать значение из диалога?
Всем привет. Ребята как сдиалога возврашат значения (переменную) делаю так MyDlg a,s;...


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
Как написать микросервис на C# с Kafka, MediatR, Redis и GitLab CI/CD
InfoMaster 15.01.2025
В современной разработке программного обеспечения микросервисная архитектура стала стандартом де-факто для создания масштабируемых и гибких приложений. Этот подход позволяет разделить сложную систему. . .
Что такое CQRS и как это реализовать на C# с MediatR
InfoMaster 15.01.2025
Концепция CQRS и её роль в современной разработке В современном мире разработки программного обеспечения архитектурные паттерны играют ключевую роль в создании масштабируемых и поддерживаемых. . .
Как настроить CI/CD с Azure DevOps
InfoMaster 15.01.2025
CI/ CD, или непрерывная интеграция и непрерывное развертывание, представляет собой современный подход к разработке программного обеспечения, который позволяет автоматизировать и оптимизировать процесс. . .
Как настроить CI/CD с помощью Jenkins
InfoMaster 15.01.2025
Введение в CI/ CD и Jenkins В современной разработке программного обеспечения непрерывная интеграция (CI) и непрерывная доставка (CD) стали неотъемлемыми элементами процесса создания качественных. . .
Как написать микросервис на Go/Golang с Kafka и GitHub CI/CD
InfoMaster 14.01.2025
Определение микросервиса, преимущества использования Go/ Golang Микросервис – это архитектурный подход к разработке программного обеспечения, при котором приложение состоит из небольших, независимо. . .
Как написать микросервис с нуля на C# с RabbitMQ, CQRS и CI/CD
InfoMaster 14.01.2025
В современном мире разработки программного обеспечения микросервисная архитектура стала стандартом де-факто для создания масштабируемых и гибких приложений. Этот архитектурный подход предполагает. . .
Как создать интернет-магазин на PHP и JavaScript
InfoMaster 14.01.2025
В современном мире электронная коммерция стала неотъемлемой частью бизнеса. Создание собственного интернет-магазина открывает широкие возможности для предпринимателей, позволяя достичь большей. . .
Как написать Тетрис на Ассемблере
InfoMaster 14.01.2025
Тетрис – одна из самых узнаваемых и популярных компьютерных игр, созданная в 1984 году советским программистом Алексеем Пажитновым. За прошедшие десятилетия она завоевала симпатии миллионы людей по. . .
Как создать игру "Танчики" на Unity3d и C#
InfoMaster 14.01.2025
Разработка игр – это увлекательный процесс, сочетающий в себе творчество и технические навыки. В этой статье мы рассмотрим создание классической игры "Танчики" с использованием Unity3D и языка. . .
Организую платный онлайн микро-курс по доработке Android-клиента Telegram
_Ivana 14.01.2025
Официальная версия и распространенные форки не полностью устраивают? Сделай свою кастомную версию клиента! 4 занятия по 2 часа (2 недели пн, ср 19:00-21:00 по Москве). Первое вводное занятие. . .
Как создать приложение для фитнеса для iOS/iPhone на Kotlin
InfoMaster 14.01.2025
Создание собственного фитнес-приложения — это не только захватывающий, но и полезный процесс, ведь оно может стать вашим верным помощником на пути к здоровому и активному образу жизни. В современных. . .
Как создать приложение магазина для iOS/iPhone на Swift
InfoMaster 14.01.2025
Введение в разработку iOS-приложений Разработка приложений для iPhone и других устройств на базе iOS открывает огромные возможности для создания инновационных мобильных решений. В данной статье мы. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru