如何在 C++ 中同时重载 = 和 [] 运算符
How can I overload = and [] operators at the same time in c++
这里我想通过重载 [] 和 = 运算符来摆脱插入函数。
通过重载 [] 运算符,我已经成功返回了我想要插入值的所需位置的地址。
#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[]
的 return 类型来实现理想的行为:
int& operator[](int at)
在您的原始代码中,它 return 是指向数组元素的指针,即使更改,也不会对数组中存储的值执行任何操作。使用您的原始代码,您可以编写如下内容来更改元素的值:
*(arr[5]) = 10;
看起来不明显。
如果你return引用而不是指针,你可以直接改变它引用的值。
您不需要为了您的目的而覆盖赋值运算符“=”。仅重载访问运算符“[]”。
那应该看起来像这样:
returntype& operator [](int indexvariable);
这将为您提供对 returntype 实例的引用,因此您不需要在您的情况下重载 returntype 的赋值运算符。
那你可以这样写:
arr[5] = 23;
您几乎可以通过一些技巧实现任何理想的行为。
在你的情况下,如果你想对 operator=
进行一些特定的操作(例如检查边界并插入一个新元素),你可以引入一个助手 class,它将保存对数组和索引的引用,然后为 class 重载 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); }
};
当然,您将 ARRAY
的 operator[]
调整为 return ArrayIndex
对象。
如果您不想插入或任何异常操作,而只想访问元素,那么 operator[]
return 引用 (int&
) 就足够了。
根据 OP 在 上留下的评论,我建议将您的 operator[]
更改为 return 元素的处理程序。
#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] << "\n\n";
arr[0] = 137;
std::cout
<< std::hex << &arr._value << "\n"
<< std::dec << arr._value << "\n"
<< *arr[0] << "\n\n";
int* pvalue = arr[0];
*pvalue = 0;
std::cout
<< std::hex << &arr._value << "\n"
<< std::dec << arr._value << "\n"
<< *arr[0] << "\n\n";
}
输出
g++ -std=c++17 -O2 -Wall -Werror main.cpp && ./a.out
0x7ffd682844f0
42
42
0x7ffd682844f0
137
137
0x7ffd682844f0
0
0
此处理程序可以隐式转换为 int*
,您 可以 重载其上的 operator=
。
这里我想通过重载 [] 和 = 运算符来摆脱插入函数。 通过重载 [] 运算符,我已经成功返回了我想要插入值的所需位置的地址。
#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[]
的 return 类型来实现理想的行为:
int& operator[](int at)
在您的原始代码中,它 return 是指向数组元素的指针,即使更改,也不会对数组中存储的值执行任何操作。使用您的原始代码,您可以编写如下内容来更改元素的值:
*(arr[5]) = 10;
看起来不明显。
如果你return引用而不是指针,你可以直接改变它引用的值。
您不需要为了您的目的而覆盖赋值运算符“=”。仅重载访问运算符“[]”。 那应该看起来像这样:
returntype& operator [](int indexvariable);
这将为您提供对 returntype 实例的引用,因此您不需要在您的情况下重载 returntype 的赋值运算符。
那你可以这样写:
arr[5] = 23;
您几乎可以通过一些技巧实现任何理想的行为。
在你的情况下,如果你想对 operator=
进行一些特定的操作(例如检查边界并插入一个新元素),你可以引入一个助手 class,它将保存对数组和索引的引用,然后为 class 重载 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); }
};
当然,您将 ARRAY
的 operator[]
调整为 return ArrayIndex
对象。
如果您不想插入或任何异常操作,而只想访问元素,那么 operator[]
return 引用 (int&
) 就足够了。
根据 OP 在 operator[]
更改为 return 元素的处理程序。
#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] << "\n\n";
arr[0] = 137;
std::cout
<< std::hex << &arr._value << "\n"
<< std::dec << arr._value << "\n"
<< *arr[0] << "\n\n";
int* pvalue = arr[0];
*pvalue = 0;
std::cout
<< std::hex << &arr._value << "\n"
<< std::dec << arr._value << "\n"
<< *arr[0] << "\n\n";
}
输出
g++ -std=c++17 -O2 -Wall -Werror main.cpp && ./a.out
0x7ffd682844f0
42
42
0x7ffd682844f0
137
137
0x7ffd682844f0
0
0
此处理程序可以隐式转换为 int*
,您 可以 重载其上的 operator=
。