【问题标题】:C++ operator [] overload not respondingC++ 运算符 [] 重载没有响应
【发布时间】:2015-05-27 23:13:22
【问题描述】:

我已经创建了类数组,但有些奇怪.. 类如下:

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”。 出了什么问题?

【问题讨论】:

  • 你需要像这样拼写你的getter调用:const_cast&lt;const array&amp;&gt;(a)[0]
  • 您的意思是说“问题在于它只是使用 setter 版本”吗?
  • 如果你能解释你想要达到的目标,那就太好了;如果您将cout 行放在一边,则代码会正确执行添加
  • IMO,OP 在最后一段中遇到了一些语言困难。他希望使用 const 运算符,但他发现正在执行的非 const 运算符。
  • 这里原谅 C 程序员,但是编译器甚至可以根据不同的返回类型选择正确的重载函数吗?我一直认为唯一重要的是函数的参数。

标签: c++ operator-overloading overloading


【解决方案1】:

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

引用倾向于衰减,在这种情况下为可变 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

【讨论】:

    【解决方案2】:

    总之

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

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

    在您的示例中,它是“读取”,但 b 不是 const,因此调用了非常量。它使用“setter”作为getter。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-26
      • 2016-02-19
      相关资源
      最近更新 更多