【问题标题】:c++ two versions of overloading subscript operatorc++两个版本的重载下标运算符
【发布时间】:2013-03-03 01:42:26
【问题描述】:

我的问题是:

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

和:

T& operator[](const int nIndex);

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

【问题讨论】:

标签: c++ operator-overloading subscript


【解决方案1】:

const 结尾的成员函数声明允许在const 对象上调用该函数。这仅对不修改对象状态的成员函数有意义。

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

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

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

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

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

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

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

【讨论】:

  • 我要补充一点,2 个类似的重载方法(const 和 non-const)是 C++ 中的常见样板
  • @sftrabbit:愚蠢的后续行动:我是否理解正确,我仍然需要定义两个独立的 const 和非 const 版本的运算符,并且这些主体将完全相同?基本上,就像 return MyDataStructure[nIndex]?
  • @SimonRighley 是的,您需要同时定义它们。您可以根据const 版本定义非const 版本,但您必须执行const_cast。最好只使用重复的实现。
【解决方案2】:

第一个

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

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

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

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

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

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

【讨论】:

    【解决方案3】:

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

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

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

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

    T& operator[](const int nIndex);
    

    【讨论】:

      【解决方案4】:

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

      const vector<int> mints;
      
      mints[3] = 5; // not allowed by compiler
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-11-18
        • 2012-06-21
        • 2014-04-19
        • 1970-01-01
        • 2015-09-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多