7

I have overloaded [] operator in my class Interval to return minutes or seconds.

But I am not sure how to assign values to minutes or second using [] operator.

For example : I can use this statement

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

but I want to overload [] operator, so that I can even assign values to minutes or seconds using

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

My code :

#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;

}

I know I have to declare member variables as private, but I have declared here as public just for my convenience.

nitin_cherian
  • 6,405
  • 21
  • 76
  • 127
Searock
  • 6,278
  • 11
  • 62
  • 98
  • 7
    that seems like a terrible example of operator overloading for the sake of it. Do you have some obscure requirement that forces you to do this? Otherwise it's just code obfuscation. – jalf Oct 04 '10 at 10:55
  • @jalf I know it's a terrible example, but I wanted to overload [] operator in generic class for Object Array. – Searock Oct 04 '10 at 11:06
  • @jalf: why http://cpp.sh/4fiz works without any compiler error ? Shouldn't compiler throw an error ? It gives nothing as an output. What is exactly happening in this program. – Destructor May 09 '16 at 09:03

7 Answers7

11

Return a reference to the member in question, instead of its value:

long &operator[](int index)
{
    if (index == 0)
        return seconds;
    else
        return minutes;
}
Fred Foo
  • 355,277
  • 75
  • 744
  • 836
8

Change the function signature by removing the const and returning a reference:

long& operator[](int index)

Now you will be able to write statements like:

a[0] = 12;
Vijay Mathew
  • 26,737
  • 4
  • 62
  • 93
6

Overloading op[] to use hardcoded "index" values doesn't make sense here, and you actually already have the solution in your class definition:

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

You can turn those into methods instead of public data members, that's inconsequential for not overloading op[]. However, since you want write access as well, the only advantage a method would have is validation (e.g. checking 0 <= seconds < 60).

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;
  • I know it does not make any sense, but still what should I do If I want to assign values using [] operator. – Searock Oct 04 '10 at 10:46
  • 3
    @Searock: Another answer covers it, but I won't recommend it as a solution for this problem. –  Oct 04 '10 at 10:50
  • @Roger Pate +1 I know this is a very big stupid example but it's just to clear my doubt, my ma'am told me that overloading [] operator for assigning is not possible. – Searock Oct 04 '10 at 15:06
3

return by reference to be able to assign values and use them on the LHS of the assignment operator.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • I am a beginner in c++, so can you please give me an example? – Searock Oct 04 '10 at 10:43
  • 2
    @Searock sorry i was about to add the example. Just noticied Vijay already added the snippet. Please refer that. In general in C++ if you want to be able to use value returned by your overriden operator function on LHS of assignment then you should be returning by reference in your overriden operator function. – Alok Save Oct 04 '10 at 10:48
3

converting the method to as given below should do it:

long& operator[](int index) 
kartheek
  • 763
  • 3
  • 7
1

Your array index member operator should be provided as

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

long const& operator[](int index) const;        // for const object expressions
Chubsdad
  • 24,777
  • 4
  • 73
  • 129
1

In-order to avoid confusion in the case of overloading the sub-script operator, it is recommended to use the const and non-const version of the sub-script operator.

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

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

With A[1] = 5, you are trying to modify the object at index 1. So the non-const version of the sub-script operator will be invoked automatically.

With cout << A[1], you are not modifying the object at index 1. So the const version of the sub-script operator will be invoked automatically.

nitin_cherian
  • 6,405
  • 21
  • 76
  • 127