Перегрузка подстрочного оператора "[]" в случаях l-значения и r-значения - PullRequest
6 голосов
/ 04 октября 2010

В моем классе перегружен оператор [] Интервал для возврата минут или секунд .

Но я не уверен, какприсваивать значения минутам или секундам с помощью оператора [].

Например: я могу использовать этот оператор

cout << a[1] << "min and " << a[0] << "sec" << endl;

но я хочу перегрузить оператор [], чтобы я мог даже присвоить значения минутам или секундам, используя

a[1] = 5;
a[0] = 10;

Мой код:

#include <iostream>

using namespace std;

class Interval
{

public:

    long minutes;
    long seconds;

    Interval(long m, long s)
    {
        minutes = m + s / 60;
        seconds = s % 60;
    }

    void Print() const
    {
        cout << minutes << ':' << seconds << endl;
    }

    long operator[](int index) const
    {
        if(index == 0)
            return seconds;

        return minutes;
    }

};

int main(void)
{
    Interval a(5, 75);
    a.Print();
    cout << endl;

    cout << a[1] << "min and " << a[0] << "sec" << endl;
    cout << endl;

}

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

Ответы [ 7 ]

11 голосов
/ 04 октября 2010

Возвращает ссылку на рассматриваемый элемент вместо его значения:

long &operator[](int index)
{
    if (index == 0)
        return seconds;
    else
        return minutes;
}
8 голосов
/ 04 октября 2010

Измените сигнатуру функции, удалив const и вернув ссылку:

long& operator[](int index)

Теперь вы сможете писать операторы вроде:

a[0] = 12;
6 голосов
/ 04 октября 2010

Перегрузка op [] для использования жестко закодированных значений «index» здесь не имеет смысла, и у вас уже есть решение в вашем определении класса:

cout << a.minutes << "min and " << a.seconds << "sec" << endl;

Вы можете превратить их в методы вместопубличные члены данных, это несущественно для того, чтобы не перегружать op [].Однако, поскольку вы также хотите получить доступ для записи, единственным преимуществом метода будет проверка (например, проверка 0 <= секунд <60). </p>

struct Interval {
  int minutes() const { return _minutes; }
  void minutes(int n) { _minutes = n; }  // allows negative values, etc.

  int seconds() const { return _seconds; }
  void seconds(int n) {
    if (0 <= n and n < 60) {
      _seconds = n;
    }
    else {
      throw std::logic_error("invalid seconds value");
    }
  }

  // rest of class definition much like you have it

private:
  int _minutes, _seconds;
};

// ...
cout << a.minutes() << "min and " << a.seconds() << "sec" << endl;
3 голосов
/ 04 октября 2010

преобразование метода в приведенное ниже значение должно сделать это:

long& operator[](int index) 
3 голосов
/ 04 октября 2010

возврат по ссылке, чтобы иметь возможность назначать значения и использовать их на LHS оператора присваивания.

1 голос
/ 20 января 2012

Во избежание путаницы в случае перегрузки оператора под-сценария, рекомендуется использовать версию оператора под-сценария const и non-const.

long& operator[](int index);  // non-const function returning reference

long const& operator[](int index) const;// const function returning const reference

С A[1] = 5 вы пытаетесь изменить объект на index 1. Таким образом, неконстантная версия оператора подпрограммы будет вызываться автоматически.

С cout << A[1] вы не изменяете объект на index 1. Таким образом, константная версия оператора сценария будет вызываться автоматически.

1 голос
/ 04 октября 2010

Ваш оператор члена индекса массива должен быть представлен как

long& operator[](int index);                    // for non const object expressions

long const& operator[](int index) const;        // for const object expressions
...