перегрузка оператора присваивания с оператором индекса

Я перегружен как оператор подписки и оператор присваивания, и я пытаюсь получить правильное значение для оператора присваивания
пример
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;
}

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

Другие решения

Написанный вами оператор присваивания будет применяться к массиву, а не к элементу массива. Например

x = 5;

будет использовать ваш оператор присваивания. Судя по всему, вы хотите применить перегруженный оператор присваивания при использовании оператора индекса. Единственный способ заставить что-то подобное работать — использовать прокси-класс:

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

Вы перегружены operator= для Array класс, не для int (что вы не можете сделать, кстати). x[1]=5; использует Array::operator[] для доступа к элементу, который возвращает int&, а затем использует нормальный int оператор присваивания для =5 часть. Array::operator= используется только когда вы присваиваете весь объект (то есть, как вы его определили, вы можете сделать x = 5;), не к его элементам / членам.

0

Что ты хочешь operator= сделать? Я хотел бы предложить лучшую подпись

Array& operator=(int x)

и он должен (я) вернуть ссылку на себя *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)
0

Если вы удалите перегрузку = оператор в вашем коде, то вы уже будете иметь желаемое поведение, так как ваш перегружен [] Оператор возвращает ссылку на элемент списка. Например:

#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] $ и элемент за пределами длины массива.

0
По вопросам рекламы [email protected]