我重载了下标运算符和赋值运算符,我正在尝试为赋值运算符获取正确的值
例
Array x;
x[0]=5;
通过重载下标运算符我可以得到值0,但是当我重载赋值运算符时,它执行赋值但它不使用我的重载函数,因为可变2应该具有值5.
class Array
{
public:
int *ptr;
int one,two;
Array(int arr[])
{
ptr=arr;
}
int &operator[](int index)
{
one=index;
return ptr[index];
}
int & operator=(int x){
two=x;
return x;
}
};
int main(void)
{
int y[]={1,2,3,4};
Array x(y);
x[1]=5;
cout<<x[0]<<endl;
}
答案 0 :(得分:2)
它不会使用您的operator=
,因为您没有分配给Array
的实例,而是指定给int
。这将调用您的运营商:
Array x;
x = 7;
如果要拦截operator[]
返回的赋值,必须让它返回一个代理对象并为该代理定义赋值运算符。例如:
class Array
{
class Proxy
{
Array &a;
int idx;
public:
Proxy(Array &a, int idx) : a(a), idx(idx) {}
int& operator= (int x) { a.two = x; a.ptr[idx] = x; return a.ptr[idx]; }
};
Proxy operator[] (int index) { return Proxy(*this, index); }
};
答案 1 :(得分:1)
您编写的赋值运算符将应用于数组,而不是数组元素。例如
x = 5;
将使用您的赋值运算符。从外观上看,您希望在使用下标运算符时应用overloaed赋值运算符。使这样的事情发挥作用的唯一方法是使用代理类:
struct Proxy {
Proxy(Array* array, int* element);
void operator= (int rhs) {
array->two = rhs;
*element = rhs;
}
operator int() const { return *element; }
};
Proxy operator[](int index)
{
one=index;
return Proxy(this, ptr + index);
}
答案 2 :(得分:1)
如果您删除了代码中=
运算符的重载,那么您已经拥有了您所希望的行为,因为您的重载[]
运算符会返回对列表项。例如:
#include <iostream>
using namespace std;
template<typename T>
class Array {
private:
// This method is used to reallocate our array when the number of elements becomes equal to the length of the array.
void _grow() {
length *= 2;
T* temp = new T[length];
// Copy over the array elements
for (int i = 0; i <= current; i++) {
temp[i] = items[i];
}
// Delete the old array
delete [] items;
// Set the array pointer equal to the pointer to our new memory, then annihilate the temp pointer
items = temp;
temp = NULL;
}
public:
unsigned int length, current;
T* items;
// Constructor and destructor
Array() {
current = 0;
length = 128;
items = new T[length];
}
~Array() {
delete [] items;
items = NULL;
}
// Overload the [] operator so we can access array elements using the syntax L[i], as in Python
T& operator[] (unsigned int i) {
return items[i];
}
// Add items to the Array if there is room. If there is no room, grow the array and then add it.
void push(T b) {
if (current + 1 < length) {
items[current] = b;
current += 1;
} else {
_grow();
items[current] = b;
current += 1;
}
}
};
int main() {
Array<int> L;
L[0] = 10;
L[1] = 15;
std::cout << L[0] << endl;
std::cout << L[1] << endl;
return 0;
}
输出:
jmracek:include jmracek$ g++ Array.cpp -o a
jmracek:include jmracek$ ./a
10
15
如果我小心,我还会在我尝试和$ L [i] $以及数组长度之外的元素的情况下包含错误处理。
答案 3 :(得分:0)
您为operator=
课程重载了Array
,而不是int
(顺便说一句,您无法做到)x[1]=5;
。 Array::operator[]
正在使用int&
进行元素访问,返回int
,然后使用=5
部分的普通Array::operator=
赋值运算符。 x = 5;
仅在您分配给整个对象时使用(即您定义它的方式,您可以{{1}}),不到其元素/成员
答案 4 :(得分:0)
您希望operator=
做什么?我建议更好的签名是
Array& operator=(int x)
并且它应该(i)返回自引用*this
,并且(ii)应该更好地重新初始化其他值,即清除阵列或做类似事情可能更有意义这一点。
#include <iostream>
using namespace std;
class Array
{
public:
int *ptr;
int one,two;
Array(int arr[])
:
one(0), two(0)
{
ptr=arr;
}
int &operator[](int index)
{
one=index;
return ptr[index];
}
Array & operator=(int x){
two=x;
return *this;
}
};
std::ostream& operator<<(std::ostream& stream, const Array& array)
{
stream << "( " << array.one << ", " << array.two << ": ";
if (array.ptr)
stream << *(array.ptr);
stream << ")";
return stream;
}
int main(void)
{
int y[]={1,2,3,4};
Array x(y);
cout << "Before assigning one element: " << x << endl;
x[1]=5;
cout << "After assigning one element: " << x << endl;
x = 7;
cout << "After operator=: " << x << endl;
}
可运行的源代码位于:http://ideone.com/ejefcr
这是输出。打印格式为(one, two, ptr[0])
。我想你希望成员变量one
成为最后访问过的元素的索引吗?
Before assigning one element: ( 0, 0: 1)
After assigning one element: ( 1, 0: 1)
After operator=: ( 1, 7: 1)