2010-10-04 52 views
5

我重载[]运算符在我的课间隔返回分钟重载下标运算符“[]”中的L值和R值的情况下

但我不确定如何使用[]运算符将值分配给分钟第二个

例如:我可以用这个语句

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; 

} 

I知道我必须将成员变量声明为私有的,但为了方便起见,我已经在这里声明为public。

+7

这似乎是一个运算符重载的可怕例子。你有一些晦涩的要求,迫使你这样做?否则,它只是代码混淆。 – jalf 2010-10-04 10:55:15

+0

@jalf我知道这是一个可怕的例子,但我想在对象数组的泛型类中重载[]运算符。 – Searock 2010-10-04 11:06:36

+0

@jalf:为什么http://cpp.sh/4fiz没有任何编译器错误?不应该编译器抛出一个错误?它没有提供任何输出。这个计划究竟发生了什么。 – Destructor 2016-05-09 09:03:08

回答

10

返回参考所讨论的部件,而不是它的值:

long &operator[](int index) 
{ 
    if (index == 0) 
     return seconds; 
    else 
     return minutes; 
} 
+0

哇!这个答案如此清晰和简洁。 – ZoomIn 2014-04-28 11:17:43

3

通过引用返回,以便能够分配值并将它们用于赋值运算符的LHS。

+0

我是C++的初学者,请你举个例子吗? – Searock 2010-10-04 10:43:36

+2

@Searock对不起,我正在添加示例。刚刚通知Vijay已经添加了片段。请参考。通常在C++中,如果您希望能够使用您的overriden操作符函数在赋值的LHS中返回的值,则应该在您的overriden操作符函数中通过引用返回。 – 2010-10-04 10:48:09

6

重载运算[]使用硬编码“指数”值没有意义了,您其实已经在你的类定义的解决方案:

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

你可以把那些到方法,而不是公众数据成员,这对于不会超载op []是无关紧要的。但是,由于您也希望写入权限,因此方法的唯一优点是验证(例如,检查0 < =秒< 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; 
+0

我知道它没有任何意义,但仍然应该怎么做如果我想使用[]运算符分配值。 – Searock 2010-10-04 10:46:01

+3

@Searock:另一个答案涵盖了它,但我不会推荐它作为这个问题的解决方案。 – 2010-10-04 10:50:14

+0

@Roger Pate +1我知道这是一个非常大的愚蠢的例子,但它只是为了清除我的疑问,我的女士告诉我,重载[]运算符分配是不可能的。 – Searock 2010-10-04 15:06:23

8

更改通过删除const并返回一个参考函数签名:

long& operator[](int index) 

现在,您将能够写出这样的语句:

a[0] = 12; 
+6

不要忘记op []的const超载。 – 2010-10-04 10:48:17

+5

也就是说,不要删除现有的。 *添加*这一个。 – visitor 2010-10-04 11:05:49

+1

+1我希望我可以将您的帖子标记为答案。 – Searock 2010-10-04 15:07:44

3

的方法转化为给定下面应该这样做:

long& operator[](int index) 
1

你的数组索引构件操作者应

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

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

来提供。在-为了避免在的情况下的混淆重载子脚本运算符,建议使用constnon-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。所以子脚本运算符的非const版本将被自动调用。

使用cout << A[1],您并未修改对象index 1。因此,子脚本运算符的const版本将被自动调用。