【问题标题】:overloading assignment operator With subscript operator带下标运算符的重载赋值运算符
【发布时间】:2013-12-08 17:32:57
【问题描述】:

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

【问题讨论】:

  • 我认为@Dietmar Kühl 的答案是最好的答案。因为它还显示了运算符 int() 的用法,所以cout&lt;&lt;x[0]&lt;&lt;endl; 也可以工作。也许这应该是公认的答案。

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


【解决方案1】:

它不使用您的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[1]=5 表单中获取正确的值;所以赋值运算符应该返回对象数组
  • @user2960763 在您添加评论时,我正在添加代理使用示例。
【解决方案2】:

如果您在代码中删除 = 运算符的重载,那么您将拥有您想要的行为,因为您的重载 [] 运算符返回对列表项的引用。例如:

#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】:

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

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

    【讨论】:

    • 这应该是公认的答案。它适用于 x[0] 以及 x[1]=5。
    【解决方案4】:

    你想让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)
    

    【讨论】:

    • 我想使用数组的赋值运算符而不是普通的赋值运算符我该怎么做
    【解决方案5】:

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

    【讨论】:

    • 我想用Array类的赋值运算符不正常
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-27
    • 1970-01-01
    • 2013-03-30
    • 2013-02-14
    • 2016-08-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多