C++ 运算符 [] 重载没有响应

C++ operator [] overload not responding

我已经创建了 class 数组,但有些东西变得很奇怪。class 如下:

class array
{
    private:
        int *a_;
        size_t size_;
    public:
        array();
        array(const size_t);
        array(const arreglo &);
        ~array();
        int const &operator[](size_t)const;
        int &operator[](size_t);
        array const &operator=(const array&);
        bool empty()const;
};

[] 的重载实现是:

int const &array::operator[](size_t index)const
{
    std::cout << "getter" << std::endl; 
    return a_[index]; 
}
int & array::operator[](size_t index)
{
    std::cout << "setter" << std::endl; 
    return a_[index]; 
}

我测试代码的方式主要是:

int main()
{
    array a(7);
    a[0] = 3;
    a[1] = 6;
    a[2] = a[0] + a[1];
    array b = a;
    std::cout << b[2] << std::endl;
    return 0;
}

问题是 opertar [] 仅使用 getter 版本并通过 cout "setter" 打印,而不是 "getter"。 出了什么问题?

简而言之

void f(const array& b){
     std::cout << b[2] << std::endl;
}

b 必须是常量。所有可用的是 const 函数。

在你的例子中它是一个 "read" 但是 b 不是 const 所以调用非常量。它使用 "setter" 作为 getter。

将它们视为 "getter" 和 "setter" 变体是错误的。两者之间的区别仅仅是函数的 cv 限定和 return 类型。他们都是吸气剂。更重要的是,您正在 returning 引用类型。

引用往往会衰减,在本例中为可变 int,因此编译器更有可能接受非常量函数调用。

a[0];

此语句的默认评估是一个整数值,而不是一个引用,因此您可以执行以下操作:

if (a[0])

这是基于 a[0] 处的值而不是引用(评估引用总是正确的并且不是很有帮助)。

请记住,当在大多数语句中使用引用时,它们会衰减为引用值。

int v = a[0]; // no error, even tho v's type is not int&
int& vr = a[0]; // decays to the value a references
                // then takes a reference of that

(注意:编译器可能会省略隐含的操作集,以简单地捕获或隐含第二个语句中的原始引用)。

所以代码

a[2] = a[0] + a[1]

它首先从 a[0] 和 a[1] 获取值,知道它要进行数学运算,因此最简单的方法是:

int a1 = a.operator[](1);
int a0 = a.operator[](0);
int& dest = a.operator[](2);
dest = a0 + a1;

如果你想要 const,你将需要一个 const/const-ref 到一个数组或者指定你想要一个 const ref:

const int& ar = a[0];

#include <iostream>

struct array
{
    int i = 0;
    array() {}
    const int &operator[](size_t) const { std::cout << "const int[]\n"; return i; }
    int &operator[](size_t) { std::cout << "int[]\n"; return i; }
};

int main()
{
    array a;
    a[0];
    int v1 = a[0];
    const int v2 = a[0];
    std::cout << "refs\n";
    int& v3 = a[0];
    const int& v4 = a[0];
    std::cout << "const array\n";
    const array b;
    b[0];
    int v5 = b[0];
    const int v6 = b[0];
    std::cout << "refs\n";
    //int& v7 = b[0]; // would produce a compile error
    const int& v8 = b[0];
}

http://ideone.com/7EYGYj