【问题标题】:Multiple operator[] overloads多个 operator[] 重载
【发布时间】:2015-10-21 00:01:15
【问题描述】:

看看这个简单的数组类

class Array {
    const unsigned int _size;
    int _array[100];

public:
    Array() : _size(100) {
        for(unsigned int i = 0; i < _size; i++)
            _array[i] = 0;
    }

    int& operator[](unsigned int index) {
        cout << "normal operator[].\n";
        return _array[index];
    }

    const int& operator[](unsigned int index) const {
        cout << "const operator[].\n";
        return _array[index];
    }
};

int main()
{
    Array a;

    a[3] = 1;
    cout << a[3] << "\n";

    system("pause");
    return 0;
}

“普通运算符[]”行执行了两次,但我希望第二次调用 (cout &lt;&lt; a[3] &lt;&lt; "\n";) 使用重载运算符的 const 版本,因为它不会更改数组本身。

这是为什么呢?有没有办法强制按我的意愿调用 const 版本?

【问题讨论】:

  • a 在该表达式中不是 const,因此不会调用 const 重载。如果你想强制它,你可以使用const_cast&lt;Array const&amp;&gt;(a)[3],但它真的没有必要。
  • 那有什么意义呢?我试图模仿 std::vector 因为它还有两个重载的 operator[] 函数。您是说除非 std::vector 对象是 const (因为我认为这没有意义),否则将始终调用非常量版本?
  • unless the std::vector object is const the non-const version will always be called 这是(某种程度上)const 重载的定义,是的。请注意,底层对象本身可能是非常量的,并且通过 const 引用进行访问,这通常是这种情况。例如,在您的代码中,您也可以使用 Array const&amp; b = a; cout &lt;&lt; b[3];
  • 现在说得通了。谢谢!

标签: c++


【解决方案1】:

当你有一个重载的 const 版本的方法时,当对象是 const 时会调用 const 版本。例如:

#include <iostream>
using namespace std;

class MyClass
{
public:

    void foo()
    {
        cout << "foo()" << endl;
    }

    void foo() const
    {
        cout << "foo() const" << endl;
    }
};

int main()
{
    MyClass a;
    const MyClass b;

    a.foo();
    b.foo();

    return 0;
}

将为对象a 调用普通的foo(),为对象b 调用const 版本。

在您的情况下,您只需要避免尝试分配给 const 版本。例如:

Array a;
const Array b;

a[3] = 1;
// b[3] = 1; // error
cout << a[3] << "\n";
cout << b[3] << "\n";

工作正常。但是,如果您尝试对b 进行赋值,则会出现编译错误。

【讨论】:

    【解决方案2】:

    std::ostream &amp;operator&lt;&lt;(int x)不把它的参数当作const(因为const在传值时没有用),所以可以调用非const的operator[]

    那么,const operator[] 什么时候会被调用?

    确实,const vector 变量声明几乎总是无用的,除了一些边缘情况。 const operator[] 很重要的主要原因是,您最常看到它使用它是在引用参数上调用它。

    int readStuff(const std::vector<int> &dontMutateMe) {
        return dontMutateMe[42]; // const
    }
    

    Constant reference parameters are valuable,如果没有const operator[],此代码将无法运行。

    【讨论】:

    • std::ostream&amp; operator&lt;&lt; 的参数声明与为a 选择的重载无关,非const operator[] 如果声明为operator[] 仍会被调用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-14
    • 2010-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多