更改重载运算符以返回值而不是引用

时间:2013-06-29 18:12:37

标签: c++

如何更改重载运算符以返回值而不是引用?

#include <iostream>
using namespace std;

class IntList 
{ 
private: 
    int list[1]; 
public:
    IntList() {list[0] = 0;}
    int& operator[] (const int index) {return list[index];} 
}; 

int main()
{
    IntList list;

    cout << list[0] << endl;
    list[0] = 1;
    cout << list[0] << endl;
    return 0;
}

3 个答案:

答案 0 :(得分:3)

int operator[] (const int index){}
^^^^^

只需删除&即可。完成后,您无法使用它为数组元素赋值。

  

返回引用和非引用之间的区别

正如您在operator []返回引用时注意到的那样,它可以在赋值的左侧使用。这是可能的,因为当您通过引用返回时,operator []的返回值是l值。引用被视为l值,因为您可以引用存储在内存中并具有地址的变量 当operator []按值返回时,表达式list[0] = 1;最终会将 [#] 评估为类似的内容,

1=1;

这是不合逻辑的,因为1不是l值,编译器将生成左操作数必须为l值的诊断。

[#]假设下标0处元素的值为1

答案 1 :(得分:1)

您只需删除&就可以完成此操作,这样您就可以了 int operator[] (const int index){}
但是,正如您所注意到的那样,问题是您无法在没有编译错误的情况下分配它,因为索引运算符不再返回l值。所以我认为你应该考虑为什么要返回一个值而不是一个引用。您可能需要一种模式,其中索引运算符不能用于分配给对象,可能是某种只读类型对象。你的另一个选择是有一个单独的函数来设置它,因为索引操作符不能再用来做那个

答案 2 :(得分:0)

在您的代码示例中,您正在使用赋值,这需要您返回引用。

list[0] = 1;
list.operator[](0) = 1;
int& xref = list.operator[](0);
(xref) = 1; // <-- changed the value of list element 0.

鉴于您希望operator [](int index)返回一个值,这将转换为:

int x = list.operator[](0);
x = 1; <-- you changed x, not list[0].

如果你想让operator [](int index)返回一个值但是list [0] = 1仍然有效,那么你需要提供两个版本的运算符,这样编译器就可以确定哪个行为你试图在给定的电话中调用:

// const member, returns a value.
int operator[] (const int index) const {return list[index];} 

// non const member, which returns a reference to allow n[i] = x;
int& operator[] (const int index) {return list[index];} 

请注意,它们必须因返回类型和成员常量而不同。

#include <iostream>
using namespace std;

class IntList 
{ 
private: 
    int list[1]; 
public:
    IntList() {list[0] = 0;}
    int operator[] (const int index) const { return list[index]; }
    int& operator[] (const int index) {return list[index];} 
}; 

int main(int argc, const char** argv)
{
    IntList list;

    cout << list[0] << endl;
    list[0] = 1;
    int x = list[0];
    cout << list[0] << ", " << x << endl;
    return 0;
}

工作演示:http://ideone.com/9UEJND