11

我的问题是关于以下之间的区别:

const T& operator[](const int nIndex) const;

和:

T& operator[](const int nIndex);

为什么我需要在一个类中定义它们,目的是什么?后者还不够吗?

4

4 回答 4

17

成员函数声明const在它的末尾允许即使在const对象上也可以调用该函数。这仅对不修改对象状态的成员函数有意义。

假设您拥有的重载这些运算符的类称为X. 大概它的行为有点像一个容器,通过 this 可以访问它包含的元素operator[]

现在假设用户想要使用 a const X

const X x = /* fill it */;
use(x[0]);

是否应该允许用户这样做?大概。如果他们想要一个不可变的容器,那就让他们拥有它。如果您不提供 的const版本operator[],他们将无法执行此操作。毕竟他们并没有试图修改容器,他们只是在查看它的内容。

现在为什么要让return的const版本成为参考?因为它必须。它返回对类本身成员的引用。如果容器是并且返回了一个非引用,调用者将能够通过使用这个操作符来修改它的内部:operator[]constconstconst

const X x = /* fill it */;
x[0].modify();

哦,天哪,我们修改了状态,x即使它是const. 这会很糟糕,事实上,编译器甚至不会让你这样做。

于 2013-03-14T15:49:56.420 回答
3

这些是类的成员函数,将根据该类是否用作const上下文来选择版本。

当在上下文[]中的对象上使用时,将调用此版本。const它保留了const返回元素的-ness。

const T& operator[](const int nIndex) const;

[]当用于非const对象时,将调用此版本。它指定当您的对象不是时const,您将获得一个可以修改的元素,允许类似的代码myObject[0] = 10;

T& operator[](const int nIndex);
于 2013-03-14T15:49:10.150 回答
2

如果您正在访问的对象是const,您不希望能够修改它。编译器不允许您调用const该函数的非版本。

const vector<int> mints;

mints[3] = 5; // not allowed by compiler
于 2013-03-14T15:49:06.837 回答
2

第一个

const T& operator[](const int nIndex) const;

是一个常量方法(函数),即它保证它不会改变任何类成员变量(除非它是可变的)。

它还返回一个常量对象,这意味着您只能调用常量函数,即您只能调用末尾具有 const 的函数,类似于上面的函数。

T& 运算符[](const int nIndex);

该方法可以改变成员变量并返回一个可以调用任何类方法的对象。

我们都需要它们,因为常量对象将使用常量方法,而非常量对象将使用另一种方法。

于 2013-03-14T16:04:04.910 回答