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

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

Войти
Регистрация
Восстановить пароль
 
TanaTiX
Модератор
2746 / 1591 / 146
Регистрация: 19.02.2011
Сообщений: 5,732
#1

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

17.05.2014, 21:53. Просмотров 558. Ответов 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++):

Ошибка при перегрузке оператора >> - 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++
Изначальное задание: Используя списки написать программу, поддерживающую операцию сложения двух многочленов. Собственно все работает,...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
0x10
2460 / 1632 / 238
Регистрация: 24.11.2012
Сообщений: 4,015
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
Модератор
2746 / 1591 / 146
Регистрация: 19.02.2011
Сообщений: 5,732
17.05.2014, 22:15  [ТС] #3
0x10, попробовал - убрал оператор (это же оператор?) ссылки (&) - помогло даже без указания констант. Или в этом какой-то дополнительный смысл?
0x10
2460 / 1632 / 238
Регистрация: 24.11.2012
Сообщений: 4,015
17.05.2014, 22:17 #4
TanaTiX, const все-таки нужны, чтобы оператор можно было использовать с константными объектами. Пример - http://ideone.com/2y8xVA
Tulosba
:)
Эксперт С++
4393 / 3236 / 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
Модератор
2746 / 1591 / 146
Регистрация: 19.02.2011
Сообщений: 5,732
17.05.2014, 22:30  [ТС] #6
Цитата Сообщение от Tulosba Посмотреть сообщение
имеющиеся конструкторы можно заменить одним
Я ошибаюсь или "explicit" в данном случае - лишнее? Описание по нему прочитал, но пока не понял. Я вообще еще очень мало в плюсах понимаю...
Цитата Сообщение от Tulosba Посмотреть сообщение
Ну и имена с подчеркивания не комильфо.
А как принято называть публичные и приватные переменные/методы что бы потом можно было их комфортно отличать?
0x10
2460 / 1632 / 238
Регистрация: 24.11.2012
Сообщений: 4,015
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
:)
Эксперт С++
4393 / 3236 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
17.05.2014, 23:11 #8
Цитата Сообщение от TanaTiX Посмотреть сообщение
как принято называть публичные и приватные переменные/методы что бы потом можно было их комфортно отличать
Соглашений может быть много разных. В разных компания они разные. Упомянутого гугла можно посмотреть тут. Для приватных полей встречается ещё вариант, в котором имя должно начинаться с m (member). Хотя уже сейчас, емнип, QtCreator умеет выделять члены класса цветом и без специального формата имен.
TanaTiX
Модератор
2746 / 1591 / 146
Регистрация: 19.02.2011
Сообщений: 5,732
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
:)
Эксперт С++
4393 / 3236 / 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
Модератор
2746 / 1591 / 146
Регистрация: 19.02.2011
Сообщений: 5,732
18.05.2014, 08:39  [ТС] #11
Цитата Сообщение от Tulosba Посмотреть сообщение
Иногда такие неявные преобразования не должны выполняться и конструктор должен быть объявлен explicit.
Т.е. это в большей степени защита от дурака, чем какая-то реальная необходимость?

Не по теме:

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

0x10
2460 / 1632 / 238
Регистрация: 24.11.2012
Сообщений: 4,015
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;
}
Tulosba
:)
Эксперт С++
4393 / 3236 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
18.05.2014, 12:33 #13
Цитата Сообщение от 0x10 Посмотреть сообщение
Если конструктор по смыслу допускает преобразование одного типа в другой (в данном случае int в complex), то в принципе конструктор можно оставить без explicit.
Кстати std::complex как раз придерживается такого принципа.
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++
Здравствуйте! При создании класса комплексные числа операцию сложения определяю так complex operator + (complex&amp;a) { return...

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

Ошибка при перегрузке оператора, не знаю как исправить - 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 ...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
18.05.2014, 12:33
Ответ Создать тему
Опции темы

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