繁体   English   中英

带下标运算符的重载赋值运算符

[英]overloading assignment operator With subscript operator

我重载了下标运算符和赋值运算符,并且我试图为赋值运算符示例Array x; x[0]=5;获取正确的值Array x; x[0]=5; 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;
}

它不使用您的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); }
};

您编写的赋值运算符将应用于数组,而不是数组元素。 例如

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

如果您在代码中取消了=运算符的重载,那么您将已经具有所需的行为,因为您的重载[]运算符将返回对列表项的引用。 例如:

#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] $和元素在数组长度之外的情况下,我还将包括错误处理。

您为Array类而不是int重载了operator= (顺便说一下,您不能这样做)。 x[1]=5; 正在使用Array::operator[]进行元素访问,该方法返回int& ,然后对=5部分使用常规的int赋值运算符。 Array::operator=仅在分配给整个对象(即定义对象的方式,可以执行x = 5;而不是分配给元素/成员时使用。

您想要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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM