用于分配和检索的括号过载;const,引用

Bracket Overload for Assignment and Retrieval; const, reference

本文关键字:const 引用 分配 检索 用于      更新时间:2023-10-16

关于C++中重载括号,我的编译器正在使用mutator方法进行访问。有人能告诉我为什么吗?

1. const int & Cheese::operator [] (int i)const { return weight[i]; } //accessor
2. int & Cheese::operator [] (int i) { return weight[i]; } //mutator

例如,下面的cout命令使用赋值函数定义(上面的#2)来访问数据。

Cheese cheddar;
cout << cheddar[2] << endl;

为什么不使用第一个函数(访问器)来获取数据?我认为,由于cout只是一种检索,它会向第一个开火。

编译器如何知道要调用其中的哪一个?

编者按:为了完整起见,我指的是用作"设置器",比如

cheddar[2] = 100;

两者加在一起如下:

cheddar[2] = cheddar[1];

其中rhs只是一个"getter"。它只检索cheddar[1]的值,不更改任何内容,因此可以是const。相反,lhs括号重载cheddar[2]用作"setter";值可以更改,函数返回值不能为常量。

它为任何常量实例(如const Cheeseconst Cheese&)调用第一个实例,为可变实例调用第二个实例。

如果你关心一种方法,可以大致得到你想要的效果(特别是,执行一个函数来获得值,其他代码来设置值,这是可靠的),有一种方法可以做到。

通常的方法是返回一个代理,而不是直接返回值(或对它的引用)。代理过载operator Toperator=

template <class T>
class Proxy { 
    T value;
public:
    Proxy(T v) : value(v) {}
    // used only to get value
    operator T() const { return value; } 
    // used only to set value
    Proxy &operator=(T new_value) { 
        value = new_value;
        return *this;
    }
};

然后您的重载只返回一个实例:

Proxy<Cheese &> operator[](int i) { return Proxy<int>(weight[i]); }
Proxy<Cheese const &> operator[](int i) const { return Proxy<int>(weight[i]); }

请注意,在第二种情况下,T的类型为Cheese const &,而operator=不是const成员函数,因此在这种情况下无法使用operator=(这正是您通常想要的)。