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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
TanaTiX
Модератор
2742 / 1587 / 144
Регистрация: 19.02.2011
Сообщений: 5,713
#1

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

17.05.2014, 21:53. Просмотров 535. Ответов 12
Метки нет (Все метки)

Есть вот такой код для созданный для обучения

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)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.05.2014, 21:53     Предупреждение при перегрузке оператора
Посмотрите здесь:

Ошибка при перегрузке оператора >> - C++
Приветствую. Есть 2 класса: enum Color { white = 1, red, green, blue, yellow }; class Shape { protected: Color figureCol; ...

Ошибка при перегрузке оператора + - C++
Имеется класс, который представляет из себя строку и количество символов в ней. Задача - перегрузить оператор +, чтобы он складывал нам две...

Ошибка при перегрузке оператора cin >> - C++
#include &lt;iostream&gt; using namespace std; /////////////////////////////////////////////////////////// class fraction { ...

& при перегрузке оператора ввода - C++
Скажите почему без &amp; не будет работать? ostream&amp; operator&lt;&lt;(ostream &amp;stream,MyClass obj) { stream&lt;&lt;obj.a&lt;&lt;endl; return stream; ...

Зачем нужен const при перегрузке оператора - C++
Следующий код описывает класс СТРОКА string_. При перегрузке оператора '=' string_&amp; string_::operator=(const string_ &amp;str) ...

Преждевременный вызов деструктора при перегрузке оператора + - C++
Изначальное задание: Используя списки написать программу, поддерживающую операцию сложения двух многочленов. Собственно все работает,...

Ошибка в перегрузке оператора - при работе с массивами - C++
Текст программы: #include &lt;iostream&gt; #include &lt;windows.h&gt; using namespace std; class array { public: array(); ...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
0x10
2459 / 1631 / 238
Регистрация: 24.11.2012
Сообщений: 4,009
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
Модератор
2742 / 1587 / 144
Регистрация: 19.02.2011
Сообщений: 5,713
17.05.2014, 22:15  [ТС]     Предупреждение при перегрузке оператора #3
0x10, попробовал - убрал оператор (это же оператор?) ссылки (&) - помогло даже без указания констант. Или в этом какой-то дополнительный смысл?
0x10
2459 / 1631 / 238
Регистрация: 24.11.2012
Сообщений: 4,009
17.05.2014, 22:17     Предупреждение при перегрузке оператора #4
TanaTiX, const все-таки нужны, чтобы оператор можно было использовать с константными объектами. Пример - http://ideone.com/2y8xVA
Tulosba
:)
Эксперт С++
4392 / 3235 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
17.05.2014, 22:19     Предупреждение при перегрузке оператора #5
Ещё имеющиеся конструкторы можно заменить одним:
C++
1
explicit complex(double re=0, double im=0) _re(re), _im(im) { }
Ну и имена с подчеркивания не комильфо.
TanaTiX
Модератор
2742 / 1587 / 144
Регистрация: 19.02.2011
Сообщений: 5,713
17.05.2014, 22:30  [ТС]     Предупреждение при перегрузке оператора #6
Цитата Сообщение от Tulosba Посмотреть сообщение
имеющиеся конструкторы можно заменить одним
Я ошибаюсь или "explicit" в данном случае - лишнее? Описание по нему прочитал, но пока не понял. Я вообще еще очень мало в плюсах понимаю...
Цитата Сообщение от Tulosba Посмотреть сообщение
Ну и имена с подчеркивания не комильфо.
А как принято называть публичные и приватные переменные/методы что бы потом можно было их комфортно отличать?
0x10
2459 / 1631 / 238
Регистрация: 24.11.2012
Сообщений: 4,009
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
:)
Эксперт С++
4392 / 3235 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
17.05.2014, 23:11     Предупреждение при перегрузке оператора #8
Цитата Сообщение от TanaTiX Посмотреть сообщение
как принято называть публичные и приватные переменные/методы что бы потом можно было их комфортно отличать
Соглашений может быть много разных. В разных компания они разные. Упомянутого гугла можно посмотреть тут. Для приватных полей встречается ещё вариант, в котором имя должно начинаться с m (member). Хотя уже сейчас, емнип, QtCreator умеет выделять члены класса цветом и без специального формата имен.
TanaTiX
Модератор
2742 / 1587 / 144
Регистрация: 19.02.2011
Сообщений: 5,713
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
:)
Эксперт С++
4392 / 3235 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
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
Модератор
2742 / 1587 / 144
Регистрация: 19.02.2011
Сообщений: 5,713
18.05.2014, 08:39  [ТС]     Предупреждение при перегрузке оператора #11
Цитата Сообщение от Tulosba Посмотреть сообщение
Иногда такие неявные преобразования не должны выполняться и конструктор должен быть объявлен explicit.
Т.е. это в большей степени защита от дурака, чем какая-то реальная необходимость?

Не по теме:

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

0x10
2459 / 1631 / 238
Регистрация: 24.11.2012
Сообщений: 4,009
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++
Добрый день, есть такой кусок кода: #include &lt;iostream&gt; #include &lt;ostream&gt; using std::ostream; using namespace std; ...

Ошибка при перегрузке оператора, не знаю как исправить - C++
#pragma once #include &lt;iostream&gt; #include &lt;vector&gt; #define innerVectorType std::vector&lt;T&gt; template &lt;class T&gt; class Matrix ...

От каких ошибок страхует Const при перегрузке оператора присваивания - C++
Здравствуйте. Вопрос имею теоретический. В классе A перегружается оператор присваивания, объявление выглядит так: const A operator =...

Почему при перегрузке оператора присваивания, возвращаемое значение не константно? - C++
Почему при перегрузке оператора присваивания, возвращаемое значение - someClass &amp; operator=(const someClass&amp; rhl), а не const someClass &amp;...

Уточняющий вопрос: почему при перегрузке оператора [] необходимо возвращать ссылку? - C++
Сабж. Ну, то есть есть класс, что-то такое: #include &lt;iostream&gt; using namespace std; class arr { public: explicit...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru