使用和不使用 const/ampersand 的 C++ 方括号重载

C++ square bracket overloading with and without const/ampersand

我正在编写 C++ 代码,并且 运行 我希望为我的 class 重载方括号运算符。从各种来源,我发现您通常使用两种方法来执行此操作,一种使用 const 关键字,另一种不使用 const 关键字,但在方法名称。下面给出一个例子。

int MyClass::operator[](unsigned int i) const {
    return this->values[i];
}

int & MyClass::operator[](unsigned int i) {
    return this->values[i];
}

我的问题如下:

  1. 为什么我有两种方法,一种有 const 关键字,一种没有?
  2. 第二种方法中的符号 (&) 有什么作用?
  3. 当我的 none 个方法是 setter 时,为什么我可以使用方括号在给定索引处设置一个值,并且当我设置一个值时调用这两个方法中的哪一个?

Why do I have two methods, one with the const keyword, and one without it?

const关键字设置了一个约束,防止函数修改对象。例如,如果您在 setter 中使用 const 关键字,则会出现编译器错误。

因此第一个函数不允许对对象进行任何修改,在这种情况下它将return 访问元素的副本。第一个函数是伪装的getter,可以说是只读访问。

What does the ampersand (&) in my second method do?

相反,第二个函数在类型后面有一个符号,这意味着它将 return returned 值的引用 和不是它的副本。 returned 值是对象的一部分,因此 return 对它的引用意味着可能的修改,而 const 关键字不允许它。

所以这第二个函数是伪装的setter,它是写入访问。

Why can I set a value at a given index using square brackets, when none of my methods are setters, and which of these two methods is invoked when I set a value?

正如我们所见,第二个函数的作用类似于 setter。当您使用它时,returned 值是对对象内部真实元素的引用,并且对赋值有效(我们称其为左值,更多关于它们 here)。

此重载的要点是:每当您使用运算符进行读取操作(赋值的右侧或作为参数)时,第一个函数将被调用。如果您将它用于写操作,它将是第二个。事实上,这就是您可能在代码中使用的相同运算符对 STL 容器的工作方式。