重载赋值运算符用下标运算符

时间:2013-11-23 22:13:07

标签: c++ operator-overloading overloading assignment-operator subscript

我重载了下标运算符和赋值运算符,我正在尝试为赋值运算符获取正确的值 例  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;
}

5 个答案:

答案 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)