Ошибка перегрузки оператора C ++: назначение элемента "" в объекте только для чтения - PullRequest
1 голос
/ 25 марта 2020

Сообщение об ошибке:

class.cpp: In function 'RationalNumber operator++(const RationalNumber&, int)':
class.cpp:27:28: error: assignment of member 'RationalNumber::numerator' in read-only object
  r.numerator = r.numerator+1;

Почему это «в объекте только для чтения»?

файл class.h

#ifndef CLASS_H
#define CLASS_H
#include <iostream>
using namespace std;
// #include "class2.h"

class RationalNumber
{
 private:
  int numerator,denominator;
 public:
    RationalNumber(int x,int y);
    RationalNumber();
    friend ostream& operator << (ostream& os,const RationalNumber& x);
    friend RationalNumber operator++ (const RationalNumber& r, int dummy);
    RationalNumber operator- (const RationalNumber& r) {
        RationalNumber r3;
        //cout << numerator << " " << r.numerator<<endl;
        r3.numerator = (numerator * r.denominator)-(r.numerator * denominator);
        r3.denominator = r.denominator * denominator;
        return r3;
    }

};
#endif

main. cpp

#include <iostream>
using namespace std;
#include "class.h"
// #include "class2.h"

int main()
{
    RationalNumber r1(21,7),r2(67,31),r3;
    r3 = r1 - r2;
    cout << r3;
    r1++;
    cout << r1;
}

cpp часть с ошибкой

RationalNumber operator++ (const RationalNumber& r, int dummy) 
{
    RationalNumber temp;
    temp = r;
    r.numerator = r.numerator+1;
    return temp;
}

Ответы [ 2 ]

1 голос
/ 25 марта 2020

Предположительно, вы намеревались изменить значение temp на operator++(); если это так, у вас есть опечатка, вызывающая ошибку, когда вы пытаетесь изменить r, который является const объектом. Вы, вероятно, хотели написать:

RationalNumber operator++ (const RationalNumber& r, int dummy) 
{
    RationalNumber temp;
    temp = r;
    temp.numerator = temp.numerator+1; // NOT "r.numerator = ..."
    return temp;
}

(который может быть несколько сокращен или изменен различными способами; для ясности я оставил ваш оригинальный стиль кодирования. Возможно, вы также получаете предупреждение компилятора за неиспользование int аргумент dummy).

Учитывая, что вы на самом деле не используете int dummy, можно предположить, что вы пытаетесь написать префикс ++ а не тот постфикс, который вы написали. Как видно из этого ответа , синтаксис немного отличается; вы бы написали что-то вроде

RationalNumber& operator++() // no args: prefix
{
    ++(this->numerator); 
    return *this;
}

Хотя это и исправит ошибку компилятора, вы должны сделать резервную копию в несколько шагов и определить, действительно ли operator++() имеет смысл для вашего класса; Есть несколько разумных значений, которые можно установить sh для ++. Вы, вероятно, хотите, чтобы operator+() добавил два RationalNumber s вместо "увеличения".

0 голосов
/ 25 марта 2020

Как указано, оператор const указывает, что вы не можете изменить r. Вот правильное объявление и реализация вашего оператора postfix ++:

...
    friend RationalNumber& operator++ (RationalNumber& r, int dummy);
...
RationalNumber& operator++ (RationalNumber& r, int dummy) 
{
    r.numerator += 1;
    return r;
}

Однако, как уже отмечалось, использование оператора приращения сбивает с толку, как это. Казалось бы, имеет больше смысла, если бы она увеличила дробь на 1 целое, а не на числитель на 1. Как 3/7 + 1 = 10/7
Вместо этого вы делаете 3/7 + 1/7 = 4 / 7

Примечание. Я удалил переменную temp, чтобы вы возвращали исходный объект, потому что это именно то, для чего предназначен оператор, а не для создания нового объекта.

...