Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
3 / 3 / 0
Регистрация: 18.11.2015
Сообщений: 77
1

Оператор присваивания

26.02.2018, 19:38. Просмотров 1047. Ответов 10
Метки нет (Все метки)


Здравствуйте!
Есть класс, в котором перегружены операции сложения и присваивания:
C++
1
2
void operator = (Matrix&);
Matrix operator + (Matrix&);
При сложении с присваиванием(a,b и c - объекты этого класса):
C++
1
a = b + c;
возникает ошибка при компиляции.
Если не передавать объект по ссылке в функцию присваивания, то всё будет хорошо.
Но объясните, пожалуйста, почему возникает проблема при передаче по ссылке: вроде бы оператор присваивания возвращает объект, равный a+b, а затем этот объект должен передаться по ссылке при присваивании. Где я не прав?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
26.02.2018, 19:38
Ответы с готовыми решениями:

Для шаблонного класса перегрузить оператор присваивания, copy-конструктор, объекты cin и cout, оператор *
Помогите в следующем: Для класса шаблона следует перегрузить оператор присваивания, конструктор...

Оператор присваивания в c++
Такой вопрос, для каких классов следует явно перегрузить оператор присваивания??

оператор присваивания
Привет всем ! Каким образом вызывается оператор присваивания, например, здесь: a = "I "; если в...

оператор присваивания
Подскажите пожалуйста, вот я создал класс, конструктор которого создает 2хмерный массив из 2ойного...

__________________
Помогаю в написании студенческих работ здесь.
Записывайтесь на профессиональные курсы C++ разработчиков
10
"C with Classes"
1622 / 1245 / 474
Регистрация: 16.08.2014
Сообщений: 5,222
Записей в блоге: 1
26.02.2018, 19:42 2
DmmiTrY, по ходу у тебя в реализации операторов ошибка. скинь ее тоже.

Добавлено через 1 минуту
DmmiTrY, operator = обычно ссылку возвращает так как может стоять в цепочке операторов.
0
3 / 3 / 0
Регистрация: 18.11.2015
Сообщений: 77
26.02.2018, 20:18  [ТС] 3
_stanislav,
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
void Matrix::operator = (Matrix &m)
{
    if((N != m.N)||(M != m.M))
    {
       cout<<"Matrix sizes are not equal!"<<endl;
       exit(1);
    }
 
    for(int i = 0; i<N; ++i)
        for(int j = 0; j<M; ++j)
            Matr[i][j] = m.Matr[i][j];
 
}
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
Matrix Matrix::operator+(Matrix m)
{
    if((N != m.N)||(M != m.M))
    {
       cout<<"Matrix sizes are not equal!"<<endl;
       exit(1);
    }
 
    Matrix x(N,M);
    for(int i = 0; i<N; ++i)
    {
        for(int j = 0; j<M; ++j)
        {
            x.Matr[i][j] = Matr[i][j];
        }
    }
 
    for(int i = 0; i<N; ++i)
    {
        for(int j = 0; j<M; ++j)
        {
            x.Matr[i][j] += m.Matr[i][j];
        }
    }
 
    return x;
}
0
"C with Classes"
1622 / 1245 / 474
Регистрация: 16.08.2014
Сообщений: 5,222
Записей в блоге: 1
26.02.2018, 20:41 4
Цитата Сообщение от DmmiTrY Посмотреть сообщение
x.Matr
что такое Matr? скинь весь код
0
С чаем беда...
Эксперт CЭксперт С++
8525 / 4243 / 1173
Регистрация: 18.10.2014
Сообщений: 9,212
26.02.2018, 20:45 5
Цитата Сообщение от DmmiTrY Посмотреть сообщение
Но объясните, пожалуйста, почему возникает проблема при передаче по ссылке: вроде бы оператор присваивания возвращает объект, равный a+b, а затем этот объект должен передаться по ссылке при присваивании.
Верно. Но ваш оператор присваивания возвращает временный объект, равный a+b. Ко временному объекту нельзя привязать неконстантную lvalue-ссылку Matrix&. Отсюда и ошибка компиляции.

Без правильного использования const эту функциональность реализовать не получится. Должно быть

C++
1
2
void operator = (const Matrix&);
Matrix operator + (const Matrix&) const;
Более того, оператор + лучше реализовывать самостоятельной функцией, а не методом класса.
1
301 / 213 / 74
Регистрация: 23.05.2011
Сообщений: 970
26.02.2018, 20:53 6
Цитата Сообщение от DmmiTrY Посмотреть сообщение
void operator = (Matrix&);
Проблема в том, что изменяемыми ссылками T& могут быть только ссылки на lvalue (значения, которые могут "стоять слева" при присваивании).
То есть, это должны быть изменяемые переменные, например.

А в выражении a+b у тебя получается вычисленное значение, то есть, rvalue. То же самое с любыми вызовами конструкторов или функций, возвращающих объекты.

У тебя должен быть оператор вида: Matrix& operator = (const Matrix&);
const T&, то есть, неизменяемая ссылка.

Вот моя тема, которую я создал буквально вчера, где разжёвывается часть.
Особенности перегрузки некоторых операторов
И да, если следовать советам оттуда, у тебя должны быть вообще операторы вида:
C++
1
2
void operator = (const Matrix&)&;
Matrix operator + (const Matrix&)const;
И это защитит тебя от ошибок вида Matrix()=a+b;
1
"C with Classes"
1622 / 1245 / 474
Регистрация: 16.08.2014
Сообщений: 5,222
Записей в блоге: 1
27.02.2018, 08:03 7
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Верно. Но ваш оператор присваивания возвращает временный объект, равный a+b.
у него оператор присваивания возвращает void

Добавлено через 1 минуту
Цитата Сообщение от DmmiTrY Посмотреть сообщение
возникает ошибка при компиляции.
конкретней
0
С чаем беда...
Эксперт CЭксперт С++
8525 / 4243 / 1173
Регистрация: 18.10.2014
Сообщений: 9,212
27.02.2018, 09:26 8
Цитата Сообщение от _stanislav Посмотреть сообщение
у него оператор присваивания возвращает void
Да, оговорился и он и я. Имелось в виду: оператор сложения возвращает временный объект, равный a+b.
0
"C with Classes"
1622 / 1245 / 474
Регистрация: 16.08.2014
Сообщений: 5,222
Записей в блоге: 1
27.02.2018, 09:36 9
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
оператор сложения возвращает временный объект
так он же возвращает объект по значению, так что ошибок быть не должно.
0
С чаем беда...
Эксперт CЭксперт С++
8525 / 4243 / 1173
Регистрация: 18.10.2014
Сообщений: 9,212
27.02.2018, 16:25 10
Цитата Сообщение от _stanislav Посмотреть сообщение
так он же возвращает объект по значению, так что ошибок быть не должно.
Не понимаю. Наоборот, именно потому, что объект возвращается по значению (т.е. возвращается временный объект), и получилась ошибка. В исходном варианте кода временный объект не может быть правой частью оператора присваивания.
0
3 / 3 / 0
Регистрация: 18.11.2015
Сообщений: 77
27.02.2018, 16:51  [ТС] 11
_stanislav, я действительно описался с оператором присваивания. Такое описание:
C++
1
2
void operator = (const Matrix&)&;
Matrix operator + (const Matrix&)const;
решает эту проблему.

New man, и TheCalligrapher, спасибо за ответ! Я думал, что const просто защищает объект от изменений. А здесь получается, что const нужен, только чтобы сообщить компилятору, что можно передавать в функцию временные объекты по ссылке. Так получается?
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
27.02.2018, 16:51

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь или здесь.

Оператор присваивания.
Всем привет!В универе щас работаем с классами и перегрузками.В частности перегрузкой оператора...

Оператор присваивания
Какая разница между оператором &quot;=&quot; и &quot;==&quot; Почему , например , в цикле нужно писать ...

Оператор присваивания
Почему в этом случае вызывается оператор присваивания Fraction f4; f4 = f1+f2+f3;...

Оператор присваивания
Добрый день! Помогите, пожалуйста, разобраться. Я не совсем понимаю работу перегруженного...


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

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

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