如何在 c++ 中同时重载 = 和 [] 运算符

How can I overload = and [] operators at the same time in c++

本文关键字:运算符 重载 c++      更新时间:2023-10-16

在这里,我想通过重载 [] 和 = 运算符来摆脱插入函数。通过重载 [] 运算符,我已成功返回要插入值的所需位置的地址。

#include<iostream>
using namespace std;
#define const maxSize = 30;
class ARRAY
{
private:
    int *ar;
    int end;
public:
    ARRAY()
    {
        ar = new int[40];
        end = -1;
    }
    void insert(int value)
    {
        end += 1;
        ar[end] = value;
    }
    void insert(int value, int index)
    {
        if (index<30 && index >-1)
        {
            int tempEnd = end;
            for (int i = end; i >= index; --i)
            {
                ar[tempEnd + 1] = ar[tempEnd];
                tempEnd -= 1;
            }
            end += 1;
            ar[index] = value;
        }
        else
            cout << "nOVERFLOW";
    }
    void remove(int index)
    {
        if (index >= 0 && index <= end)
        {
            for (int i = index; i < end; ++i){
                ar[i] = ar[i + 1];
            }
            end -= 1;
            //do something
        }
        else
            cout << "nNothing gonna happens";
    }
    void display()
    {
        for (int i = 0; i <=end; ++i)
            cout << "n" << ar[i];
    }
    int* operator[](int at)
    {
        if (at < 40){
            end++;
            return (&ar[at]);
        }
    }
    //Here I want to do = operator overloading, How can I do this?
};
int main()
{
    ARRAY arr;
    arr.insert(1);
    arr.insert(2);
    arr.insert(3);
    arr.insert(4);
    arr.insert(5);
    arr[5] = 10;
    arr.display();
    return 0;
}

您可以通过更改operator[]的返回类型来实现所需的行为:

int& operator[](int at)

在原始代码中,它返回指向数组元素的指针,即使更改了数组元素,也不会对存储在数组中的值执行任何操作。使用原始代码,您可以编写如下内容来更改元素的值:

*(arr[5]) = 10;

这看起来不明显。

如果返回引用而不是指针,则可以直接更改它引用的值。

您不需要为了您的目的而覆盖赋值运算符 '='。仅重载访问运算符"[]"。它应该看起来像这样:

returntype& operator [](int indexvariable);

这将为您提供对 returntype 实例的引用,因此在您的情况下,您不需要重载 returntype 的赋值运算符。

然后你可以写:

arr[5] = 23;

您可以通过一些技巧实现几乎任何理想的行为。
在你的情况下,如果你想对operator=执行一些特定的操作(例如,检查边界和插入一个新元素),你可以引入一个帮助程序类,它将保存对数组和索引的引用,然后重载该类的operator=

class ArrayIndex
{
  ARRAY& array;
  int index;
public:
  ArrayIndex(ARRAY& a, int i) : array(a), index(i) {}
  void operator=(int value)
   { array.insert(value,index); }
};

当然,你调整ARRAYoperator[]以返回ArrayIndex对象。

如果您不希望插入或任何异常操作,而只想访问元素,则返回引用(int&)就足够了operator[]

在 OP 对 akexeykuzmin0 的响应留下的评论之后,我建议更改您的operator[]以将处理程序返回给您的元素。

#include <iostream>
struct ARRAY
{
    struct Handler
    {
        int* _ptr;
        Handler(int* ptr) : _ptr(ptr) {}
        int& operator*() { return *_ptr; }
        operator int*() { return _ptr; }
        int& operator=(int const& value) { *_ptr = value; return **this; }
    };
    int _value;
    ARRAY(int n) : _value(n) {}
    Handler operator[](size_t) { return Handler(&_value); }
};
int main() {
    ARRAY arr(42);
    std::cout
        << std::hex << &arr._value << "n"
        << std::dec << arr._value << "n"
        << *arr[0] << "nn";
    arr[0] = 137;
    std::cout
        << std::hex << &arr._value << "n"
        << std::dec << arr._value << "n"
        << *arr[0] << "nn";
    int* pvalue = arr[0];
    *pvalue = 0;
    std::cout
        << std::hex << &arr._value << "n"
        << std::dec << arr._value << "n"
        << *arr[0] << "nn";
}

输出

g++ -std=c++17 -O2 -Wall -Werror main.cpp && ./a.out
0x7ffd682844f0
42
42
0x7ffd682844f0
137
137
0x7ffd682844f0
0
0

在科里鲁上进行现场演示

此处理程序可以隐式转换为int*并且可以重载其上的operator=