【问题标题】:Why have two functions for operator overload?为什么有两个函数用于运算符重载?
【发布时间】:2013-09-25 20:50:14
【问题描述】:

我目前正在为我的一个类使用 C++ 中的动态内存编写一个双链表。我已经写好了代码,我只是有一个问题。

我们的教授要求我们写一个

int& operator[](int position) 

和一个

int operator[](int position) const

功能。

为同一个运算符执行两个函数有什么意义?我敢肯定这背后有某种逻辑,哈哈。是不是我既可以做 a = arr[i] 也可以做 arr[i] = a?

【问题讨论】:

    标签: c++ operator-overloading pass-by-reference


    【解决方案1】:

    如果您有一个const 列表对象,您应该只能从中读取值。如果你有一个可修改的,你应该能够读取和写入值。第一个是使用const 版本完成的,它将为const 对象调用。

    【讨论】:

    • 但是既然 const 函数的能力也包含在其他函数中,那何必写呢?如果您的代码更改数据,是否只是为了让编译器的安全性对您大喊大叫?
    • @user2816987 它被非const 变体所覆盖,因为它不能在const 对象上调用。
    • @user2816987:我试图在我的回答中解释为什么要打扰。不清楚吗?
    • @LaszloPapp - 您可以拥有该列表类型的const 对象,如果这样做,编译器将不允许您调用该对象上的非const 成员函数。 C++ 编程的一个重要方面是 const 正确性:不应该修改对象的函数不应该修改。因此,只查看array 对象内容的函数应该通过const 引用来获取该对象,例如void show(const list&)。您可以使用可修改的list 对象调用该对象;编译器不会让函数修改对象。这是一件好事:更容易找到不正确的更改。
    • 我不确定你想通过这篇文章达到什么目的。
    【解决方案2】:

    当您的对象是 const 时,您只能使用 const 版本的运算符,由于是 const,它不允许修改您的对象或返回对内部成员的非 cons 指针/引用。因此,当您的对象是非常量时,您需要一个允许修改的非常量运算符,以便您可以编写 foo[i]=n

    【讨论】:

      【解决方案3】:

      1) const 变体用于阅读,例如当你给一个变量赋值时。尝试修改指定索引处的列表值时,编译器会给您一个错误。如您所写, const 的示例是 a = arr[i]

      2) non-const variant 通常在您实际设置列表的某个索引处的值时使用。尽管您也可以使用此变体来获取值。但是,当您的意图只是读取并且您的代码会意外写入时,编译器不会引发错误。这可能会导致细微的错误,您可以通过在这种情况下使用 const 来避免这些错误。如您所写,非常量的示例是 arr[i] = a

      如果您同时存在这两个版本,则当您对非常量对象执行索引时,将调用非常量版本版本进行读取。

      【讨论】:

        【解决方案4】:

        只是为了让我既可以a = arr[i] 也可以arr[i] = a 吗?

        是的,这就是它的用途。

        • 如果您有const 或非const 列表,那么您可以执行a = arr[i] 分配;
        • 返回int& 的运算符版本可以让您执行arr[i] = a,这当然需要非const 列表。

        【讨论】:

        • @LightnessRacesinOrbit - 不,它不会编译。如果 operator[] 返回 int,则不能分配给 arr[i] 的结果。
        • @PeteBecker:不,它不能。 struct T { int operator[](int) { return 3; } }; int main() { T t; t[5] = 2; } => error: lvalue required as left operand of assignment
        • @PeteBecker:是的,所以首先你声称它可以做到,现在你承认它不能。你想说什么?
        • @PeteBecker:啊,将s/can/can't/ 应用于您的第一条评论,您指出了我的回答中的一个缺陷。现在发现了。谢谢!
        • const的版本返回int&,所以赋值给结果就可以了。 const 版本返回 int,您不能分配给该结果。
        【解决方案5】:

        如果你的对象有一个 const 变量,我们就叫它A const a; 然后你只能调用 const 函数,比如你的 operator [] (...) const 的 const 重载,它只提供读取。在这种情况下,您不能调用非 const operator [] (...)

        【讨论】:

          【解决方案6】:

          如果您有一个使用const 限定符定义的双向链表对象(通常称为“常量对象”)或通过指向常量的指针或对常量的引用进行引用,您想要启用读取但不写入。 const-qualified 运算符可以做到这一点。

          如果您有一个未使用const 限定符定义的对象,或者通过指向非const 的指针或指向非const 的引用来引用,则您希望同时启用读取和写入。非const-qualified 运算符会这样做。

          因此,您费心编写两个重载的原因是为了实现这两种行为。

          如果你只想阅读,而不考虑 constness,那么你只会写const 版本,因为const-qualified 成员函数可用于与这两种情况进行交互,而非const-qualified 成员函数只能用于非const 限定对象的名称(或通过指向非常量的指针或指向非常量的引用)。

          如果您只想将operator[] 应用于非const 对象,那么您只需编写非const 限定版本。这可能看起来很奇怪,因为您不希望 operator[] 需要可修改对象,但碰巧这正是 std::mapoperator[] 所做的。

          【讨论】:

            猜你喜欢
            • 2011-01-21
            • 1970-01-01
            • 1970-01-01
            • 2010-11-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-03-25
            • 2012-03-09
            相关资源
            最近更新 更多