为什么有两个operator []的定义?

时间:2014-03-15 04:34:25

标签: c++ operators operator-overloading const

我目前正在处理来自我的数据结构课程的材料,其中涉及一个练习,我们尝试定义一个模仿矢量的类,这样我们就可以了解底层发生了什么。在我意识到operator[]有两个定义之前,一切都有意义。在上下文中:

typedef unsigned int size_type;
T& operator[] (size_type i) { return m_data[i]; }
const T& operator[] (size_type i) const { return m_data[i]; }

第一个问题:为什么有必要对operator[]进行两种定义?

第二个问题:为什么这不会引发多重定义错误?

对不起,如果有什么含糊不清或似乎很明显。我是C ++的新手,我唯一的另一个经验是使用Java。谢谢!

4 个答案:

答案 0 :(得分:2)

  

为什么必须有两个operator []的定义?

如果您想要一个可以修改其值的文件(例如obj[i] = value)而另一个不能修改(const),则必须这样做。

  
    

为什么这不会引发多重定义错误?

  

基于 $ 9.3.1 / 3州 -

  

"非静态成员函数可以声明为const,volatile或const volatile。 这些cvqualifiers会影响this指针的类型(9.3.2)。它们还影响成员函数的函数类型(8.3.5); 声明const的成员函数是const成员函数,声明volatile的成员函数是volatile成员函数,声明const volatile的成员函数是const volatile成员函数。"

也就是说,您可以使用其中一个限定符来重载函数,例如:

void func();
void func() const;

答案 1 :(得分:2)

这是一种常见的C ++模式。

constconst时,*this成员函数(即原型后的关键字const 的成员函数)适用;换句话说,如果它与const对象一起使用。由于*this是常量,因此假设无法修改它是合理的,因此operator[]必须返回一个const引用。

其他成员函数将应用于任何对象,但由于它不具有const特定对象,因此仅当*this不是const时才适用。在这种情况下,可能会修改返回的引用(object[3] = new_value;),因此返回类型不是const

答案 2 :(得分:2)

  

第一个问题:为什么有必要有两个定义   运算符[]

这些定义与const限定符(和结果类型)不同。其中一个是const并返回对内部数据的const引用。如果您的容器被声明为const,则使用它,因此对它的内容的引用也是const。如果您的contianer不是const,则使用非const运算符,以便可以修改内部数据。

  

第二个问题:为什么不抛出多重定义错误?

因为const-qualifier是函数原型的一部分,这意味着void foo();void foo() const;实际上是两种不同的方法。它允许基于用于调用方法的对象的const限定符进行重载。

答案 3 :(得分:0)

每个函数都可以通过你可以调用的signature来识别,当你在C ++函数中declare编写函数的签名时,签名看起来像

qualifiers T ( qualifiers U u ) qualifiers;
############ ------------------ ::::::::::

因此签名由我用#-概述的2部分组成,#部分是返回类型,部分{{1是函数接受的参数的描述。

关键在于,如果您使用不同的-编写相同的签名,qualifiers仍然认为这是同一函数的重新声明/重新定义,因此C++是其中的一部分签名但当比较具有相同名称的函数的多个声明/定义时,它们实际上被编译器删除。

你应该阅读更多关于限定词的内容,我在这里简化了这个概念。

您还可以在签名后添加更多限定符(我使用qualifiers概述的部分),以声明有关函数工作方式的一些属性,例如:表示您声明您的函数没有& #39; t修改它可以访问的变量。