c++ operator[]重载没有响应

C++ operator [] overload not responding

本文关键字:响应 重载 operator c++      更新时间:2023-10-16

我已经创建了类数组,有些事情很奇怪。类如下:

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]; 
}

我测试代码的方式是在这个main:

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;
}

问题是操作符[]只使用getter版本,并且通过cout打印"setter"而不打印"getter"。出了什么问题?

认为它们是"getter"answers"setter"的变体是错误的。两者之间的区别仅仅是函数和返回类型的cv-限定。它们都是getter。更重要的是,你返回的是引用类型。

引用倾向于衰减,在这种情况下为可变int,因此编译器更有可能接受非const函数调用。

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 << "refsn";
    int& v3 = a[0];
    const int& v4 = a[0];
    std::cout << "const arrayn";
    const array b;
    b[0];
    int v5 = b[0];
    const int v6 = b[0];
    std::cout << "refsn";
    //int& v7 = b[0]; // would produce a compile error
    const int& v8 = b[0];
}

见http://ideone.com/7EYGYj

总之

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

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

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