I overloaded both subscript operator and assignment operator and I am trying to get right value to assignment operator
example
Array x;
x[0]=5;
by overloading subscript operator i can get value 0 but when i overload assignment operator it does the assignment but it doesn't use my overloaded function because vaiable 2 should have value 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;
}
It does not use your operator=
because you are not assigning to an instance of Array
, you're assigning to an int
. This would invoke your operator:
Array x;
x = 7;
If you want to intercept assignments to what operator[]
returns, you must have it return a proxy object and define the assignment operator for that proxy. Example:
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); }
};
The assignment operator you wrote would apply to an array, not an array element. For example
x = 5;
would use your assignment operator. From the looks of it you want to have an overloaed assignment operator applied when using the subscript operator. The only way to get something like this to work is using a proxy class:
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);
}
You overloaded operator=
for the Array
class, not for int
(which you can't do, by the way). x[1]=5;
is using Array::operator[]
for element access, which returns an int&
, and then uses the normal int
assignment operator for the =5
part. Array::operator=
is only used when you're assigning to the whole object (i.e. the way you've defined it, you can do x = 5;
), not to its elements/members.
What do you want the operator=
to do? I would suggest a better signature is
Array& operator=(int x)
and it should (i) return a self-reference *this
, and (ii) should do a better job of re-initializing other values, i.e. it might make more sense to clear your array or do something like that.
#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;
}
Runnable source code at: http://ideone.com/ejefcr
Here is the output. Format for the printing is (one, two, ptr[0])
. I guess you want the member variable one
to be the index of the last-accessed element?
Before assigning one element: ( 0, 0: 1)
After assigning one element: ( 1, 0: 1)
After operator=: ( 1, 7: 1)
If you remove the overloading of the =
operator in your code, then you'll already have the behaviour you're desiring, since your overloaded []
operator returns a reference to the list item. For example:
#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;
}
Output:
jmracek:include jmracek$ g++ Array.cpp -o a
jmracek:include jmracek$ ./a
10
15
If I were being careful, I would also include error handling for the case where I try and $L[i]$ and element outside of the array length.