0

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

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

3 回答 3

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

只需删除&. 一旦你这样做了,你就不能用它来为数组元素赋值。

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

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

1=1;

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

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

于 2013-06-29T18:14:20.213 回答
1

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

于 2013-06-29T18:19:11.240 回答
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

于 2013-06-29T19:10:43.190 回答