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

Предупреждение при перегрузке оператора - C++

Восстановить пароль Регистрация
 
TanaTiX
Модератор
 Аватар для TanaTiX
2730 / 1575 / 143
Регистрация: 19.02.2011
Сообщений: 5,650
17.05.2014, 21:53     Предупреждение при перегрузке оператора #1
Есть вот такой код для созданный для обучения

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
#include <iostream>
 
using namespace std;
 
class complex{
private:
    double _re;
    double _im;
public:
    complex(){
        _re = 0;
        _im = 0;
    }
    complex(double re){
        _re = re;
        _im = 0;
    }
    complex(double re, double im){
        _re = re;
        _im = im;
    }
private:
    friend ostream &operator << (ostream &output, complex &c){
        output<<"[complex(" << c._re << ", " << c._im << ")]";
        return output;
    }
    friend complex &operator + (complex &a, complex &b){
        complex c (a._re + b._re, a._im + b._im);
        return c;
    }
};
 
int main()
{
    complex c(5, 6);
    cout << "Hello World!" << endl<<c<<endl;
    return 0;
}
Выдает предупреждение на перегрузку оператора +
..\Test-01\main.cpp: In function 'complex& operator+(complex&, complex&)':
..\Test-01\main.cpp:28:17: warning: reference to local variable 'c' returned [-Wreturn-local-addr]
complex c (a._re + b._re, a._im + b._im);
Что не так и как бороться?
Заранее спасибо.

Не по теме:

ЗЫ. компилирую в Qt (настройки по умолчанию), но вроде это не принципиально...

Лучшие ответы (1)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
0x10
2425 / 1597 / 232
Регистрация: 24.11.2012
Сообщений: 3,919
17.05.2014, 22:07     Предупреждение при перегрузке оператора #2
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от TanaTiX Посмотреть сообщение
warning: reference to local variable 'c' returned
Возвращается ссылка на локальную переменную.
Как решать - возвращать копию.

Добавлено через 57 секунд
C++
1
friend complex operator + (const complex &a, const complex &b)
TanaTiX
Модератор
 Аватар для TanaTiX
2730 / 1575 / 143
Регистрация: 19.02.2011
Сообщений: 5,650
17.05.2014, 22:15  [ТС]     Предупреждение при перегрузке оператора #3
0x10, попробовал - убрал оператор (это же оператор?) ссылки (&) - помогло даже без указания констант. Или в этом какой-то дополнительный смысл?
0x10
2425 / 1597 / 232
Регистрация: 24.11.2012
Сообщений: 3,919
17.05.2014, 22:17     Предупреждение при перегрузке оператора #4
TanaTiX, const все-таки нужны, чтобы оператор можно было использовать с константными объектами. Пример - http://ideone.com/2y8xVA
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
17.05.2014, 22:19     Предупреждение при перегрузке оператора #5
Ещё имеющиеся конструкторы можно заменить одним:
C++
1
explicit complex(double re=0, double im=0) _re(re), _im(im) { }
Ну и имена с подчеркивания не комильфо.
TanaTiX
Модератор
 Аватар для TanaTiX
2730 / 1575 / 143
Регистрация: 19.02.2011
Сообщений: 5,650
17.05.2014, 22:30  [ТС]     Предупреждение при перегрузке оператора #6
Цитата Сообщение от Tulosba Посмотреть сообщение
имеющиеся конструкторы можно заменить одним
Я ошибаюсь или "explicit" в данном случае - лишнее? Описание по нему прочитал, но пока не понял. Я вообще еще очень мало в плюсах понимаю...
Цитата Сообщение от Tulosba Посмотреть сообщение
Ну и имена с подчеркивания не комильфо.
А как принято называть публичные и приватные переменные/методы что бы потом можно было их комфортно отличать?
0x10
2425 / 1597 / 232
Регистрация: 24.11.2012
Сообщений: 3,919
17.05.2014, 22:32     Предупреждение при перегрузке оператора #7
Цитата Сообщение от TanaTiX Посмотреть сообщение
Я ошибаюсь или "explicit" в данном случае - лишнее?
Обычно констукторы, которые могут быть вызваны с одним аргументом, объявляют explicit. Чтобы исключить возможность неявного приведения типов при конструировании объектов:
C++
1
2
3
complex c = 7; // при exclicit конструкторе - ошибка компиляции.
void f(complex c);
f(10); // аналогично.
Цитата Сообщение от TanaTiX Посмотреть сообщение
А как принято называть публичные и приватные переменные/методы что бы потом можно было их комфортно отличать?
У гугла для приватных полей - подчеркивание в конце имени - my_private_var_.
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
17.05.2014, 23:11     Предупреждение при перегрузке оператора #8
Цитата Сообщение от TanaTiX Посмотреть сообщение
как принято называть публичные и приватные переменные/методы что бы потом можно было их комфортно отличать
Соглашений может быть много разных. В разных компания они разные. Упомянутого гугла можно посмотреть тут. Для приватных полей встречается ещё вариант, в котором имя должно начинаться с m (member). Хотя уже сейчас, емнип, QtCreator умеет выделять члены класса цветом и без специального формата имен.
TanaTiX
Модератор
 Аватар для TanaTiX
2730 / 1575 / 143
Регистрация: 19.02.2011
Сообщений: 5,650
17.05.2014, 23:13  [ТС]     Предупреждение при перегрузке оператора #9
Честно говоря, с explicit пока не понятно. В чем отличие работы программы с ним и без него?

В этом случае в случае объявления в конструкторе explicit ниже приведенную конструкцию компилятор воспримет как попытку одному типу присвоить объект другого типа?
C++
1
complex c = 7;
И это работает только в тех случаях, когда среди всех возможных конструкторов есть хотя бы один, принимающий одно значение?
Я правильно понял? Это касается всех типов объектов?

Не по теме:

Цитата Сообщение от Tulosba Посмотреть сообщение
Ещё имеющиеся конструкторы можно заменить одним:
Код C++
1
explicit complex(double re=0, double im=0) _re(re), _im(im) { }
Я это понимаю, но в ActionScript всегда один конструктор, и если один из аргументов может иметь разные типы, то часто приходится передавать нетипизированную переменную (Object), т.е. мне возможности использования нескольких конструкторов чуток не хватает - такое себе профессиональное удовольствие выходит в плюсах.

Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
17.05.2014, 23:35     Предупреждение при перегрузке оператора #10
Цитата Сообщение от TanaTiX Посмотреть сообщение
Это касается всех типов объектов?
Стоит рассматривать в каждый конкретный момент только два типа: тип слева и тип справа.
В данном случае, справа int, слева complex. Значит тут требуется иметь неявный (не explicit) конструктор с одним аргументом типа int (или типа, к которому может быть преобразован int, например long или даже char).
Иногда такие неявные преобразования не должны выполняться и конструктор должен быть объявлен explicit.
Например:
C++
1
2
std::vector<int> v = 4; // ошибка
std::vector<int> v = std::vector<int>(4); // ок

Не по теме:

Цитата Сообщение от TanaTiX Посмотреть сообщение
мне возможности использования нескольких конструкторов чуток не хватает
Ну использовать их только потому, что можно использовать, тоже не стоит Основная причина по которой следует использовать один вариант пока это возможно - исключение дублирования кода.

TanaTiX
Модератор
 Аватар для TanaTiX
2730 / 1575 / 143
Регистрация: 19.02.2011
Сообщений: 5,650
18.05.2014, 08:39  [ТС]     Предупреждение при перегрузке оператора #11
Цитата Сообщение от Tulosba Посмотреть сообщение
Иногда такие неявные преобразования не должны выполняться и конструктор должен быть объявлен explicit.
Т.е. это в большей степени защита от дурака, чем какая-то реальная необходимость?

Не по теме:

Цитата Сообщение от Tulosba Посмотреть сообщение
использовать их только потому, что можно использовать, тоже не стоит
Это скоро пройдет

0x10
2425 / 1597 / 232
Регистрация: 24.11.2012
Сообщений: 3,919
18.05.2014, 08:54     Предупреждение при перегрузке оператора #12
Цитата Сообщение от TanaTiX Посмотреть сообщение
Т.е. это в большей степени защита от дурака, чем какая-то реальная необходимость?
Я бы сказал, что защита от дурака - это реальная необходимость.
Тут дело в семантике.
Если конструктор по смыслу допускает преобразование одного типа в другой (в данном случае int в complex), то в принципе конструктор можно оставить без explicit.
А что если бы у вектора был такой не-explicit конструктор, принимающий один аргумент - размер массива? Это означало бы "целое число N может быть преобразованно в массив размерности N". Слишком сложная логика. И становится допустимым такой вот код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Vector {
public:
    Vector(int size) {}
};
 
void f(Vector n) {
    // ...
}
 
int main() {
    f(1); // А этого ли мы хотели?
    
    return 0;
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.05.2014, 12:33     Предупреждение при перегрузке оператора
Еще ссылки по теме:

& при перегрузке оператора ввода C++
От каких ошибок страхует Const при перегрузке оператора присваивания C++
C++ Преждевременный вызов деструктора при перегрузке оператора +

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

Или воспользуйтесь поиском по форуму:
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
18.05.2014, 12:33     Предупреждение при перегрузке оператора #13
Цитата Сообщение от 0x10 Посмотреть сообщение
Если конструктор по смыслу допускает преобразование одного типа в другой (в данном случае int в complex), то в принципе конструктор можно оставить без explicit.
Кстати std::complex как раз придерживается такого принципа.
Yandex
Объявления
18.05.2014, 12:33     Предупреждение при перегрузке оператора
Ответ Создать тему
Опции темы

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