Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
TanaTiX
Модератор
2793 / 1647 / 168
Регистрация: 19.02.2011
Сообщений: 5,973
Завершенные тесты: 1
#1

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

17.05.2014, 21:53. Просмотров 726. Ответов 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 (настройки по умолчанию), но вроде это не принципиально...

0
Лучшие ответы (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...

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

& при перегрузке оператора ввода
Скажите почему без &amp; не будет работать? ostream&amp; operator&lt;&lt;(ostream...

Ошибка при перегрузке оператора cin >>
#include &lt;iostream&gt; using namespace std; ...

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

Ошибка при перегрузке оператора вывода в файл
Добрый день, есть такой кусок кода: #include &lt;iostream&gt; #include...

12
0x10
2554 / 1734 / 285
Регистрация: 24.11.2012
Сообщений: 4,361
17.05.2014, 22:07 #2
Лучший ответ Сообщение было отмечено TanaTiX как решение

Решение

Цитата Сообщение от TanaTiX Посмотреть сообщение
warning: reference to local variable 'c' returned
Возвращается ссылка на локальную переменную.
Как решать - возвращать копию.

Добавлено через 57 секунд
C++
1
friend complex operator + (const complex &a, const complex &b)
1
TanaTiX
Модератор
2793 / 1647 / 168
Регистрация: 19.02.2011
Сообщений: 5,973
Завершенные тесты: 1
17.05.2014, 22:15  [ТС] #3
0x10, попробовал - убрал оператор (это же оператор?) ссылки (&) - помогло даже без указания констант. Или в этом какой-то дополнительный смысл?
0
0x10
2554 / 1734 / 285
Регистрация: 24.11.2012
Сообщений: 4,361
17.05.2014, 22:17 #4
TanaTiX, const все-таки нужны, чтобы оператор можно было использовать с константными объектами. Пример - http://ideone.com/2y8xVA
1
Tulosba
:)
Эксперт С++
4746 / 3240 / 496
Регистрация: 19.02.2013
Сообщений: 9,046
17.05.2014, 22:19 #5
Ещё имеющиеся конструкторы можно заменить одним:
C++
1
explicit complex(double re=0, double im=0) _re(re), _im(im) { }
Ну и имена с подчеркивания не комильфо.
1
TanaTiX
Модератор
2793 / 1647 / 168
Регистрация: 19.02.2011
Сообщений: 5,973
Завершенные тесты: 1
17.05.2014, 22:30  [ТС] #6
Цитата Сообщение от Tulosba Посмотреть сообщение
имеющиеся конструкторы можно заменить одним
Я ошибаюсь или "explicit" в данном случае - лишнее? Описание по нему прочитал, но пока не понял. Я вообще еще очень мало в плюсах понимаю...
Цитата Сообщение от Tulosba Посмотреть сообщение
Ну и имена с подчеркивания не комильфо.
А как принято называть публичные и приватные переменные/методы что бы потом можно было их комфортно отличать?
0
0x10
2554 / 1734 / 285
Регистрация: 24.11.2012
Сообщений: 4,361
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_.
1
Tulosba
:)
Эксперт С++
4746 / 3240 / 496
Регистрация: 19.02.2013
Сообщений: 9,046
17.05.2014, 23:11 #8
Цитата Сообщение от TanaTiX Посмотреть сообщение
как принято называть публичные и приватные переменные/методы что бы потом можно было их комфортно отличать
Соглашений может быть много разных. В разных компания они разные. Упомянутого гугла можно посмотреть тут. Для приватных полей встречается ещё вариант, в котором имя должно начинаться с m (member). Хотя уже сейчас, емнип, QtCreator умеет выделять члены класса цветом и без специального формата имен.
1
TanaTiX
Модератор
2793 / 1647 / 168
Регистрация: 19.02.2011
Сообщений: 5,973
Завершенные тесты: 1
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), т.е. мне возможности использования нескольких конструкторов чуток не хватает - такое себе профессиональное удовольствие выходит в плюсах.

0
Tulosba
:)
Эксперт С++
4746 / 3240 / 496
Регистрация: 19.02.2013
Сообщений: 9,046
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 Посмотреть сообщение
мне возможности использования нескольких конструкторов чуток не хватает
Ну использовать их только потому, что можно использовать, тоже не стоит :) Основная причина по которой следует использовать один вариант пока это возможно - исключение дублирования кода.

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

Не по теме:

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

0
0x10
2554 / 1734 / 285
Регистрация: 24.11.2012
Сообщений: 4,361
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;
}
2
Tulosba
:)
Эксперт С++
4746 / 3240 / 496
Регистрация: 19.02.2013
Сообщений: 9,046
18.05.2014, 12:33 #13
Цитата Сообщение от 0x10 Посмотреть сообщение
Если конструктор по смыслу допускает преобразование одного типа в другой (в данном случае int в complex), то в принципе конструктор можно оставить без explicit.
Кстати std::complex как раз придерживается такого принципа.
1
18.05.2014, 12:33
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.05.2014, 12:33
Привет! Вот еще темы с решениями:

Константность ссылки в параметре при перегрузке оператора
Здравствуйте! При создании класса комплексные числа операцию сложения определяю...

Зачем нужен const при перегрузке оператора
Следующий код описывает класс СТРОКА string_. При перегрузке оператора '=' ...

Ошибка в перегрузке оператора - при работе с массивами
Текст программы: #include &lt;iostream&gt; #include &lt;windows.h&gt; using namespace...

Ошибка при перегрузке оператора, не знаю как исправить
#pragma once #include &lt;iostream&gt; #include &lt;vector&gt; #define innerVectorType...


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

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