C ++中赋值运算符重载时出错

问题描述

class Array
{
private:
    int *ptr;
    int size;
    
public:
    Array& operator = (const Array& rhs);
};

Array& Array::operator = (const Array& rhs)
{
    ptr = new int [rhs.size];
    size = rhs.size;
    
    for( int i = 0; i < size; i++ )
        ptr[i] = rhs.ptr[i];
        
    return *this;
}

int main()
{
    Array a;
    Array b;    
        
    a = b;
}

代码有什么问题?

我可以观察到的第一件事是size的值尚未定义。因此会出现错误

size是私有的,因此我不能从main为其分配值,但这是赋值运算符的参数。在哪里分配值?

我尝试在=运算符的定义内分配rhs.size的值,但随后引发分段错误。为什么?

我不明白他们打算将此for循环做什么:

for( int i = 0; i < size; i++ )
        ptr[i] = rhs.ptr[i];

我想了解这段代码的情况。

解决方法

如果没有构造函数,则无法首先分配要复制的内存,也无法分配size,依此类推。您需要添加该功能以测试您的复印功能。

尽管这里仍然有很多工作要做,但我还是在这里写了一些代码来使它更具操作性:

#include <iostream>

class Array
{
private:
    int *ptr;
    int size;
    
public:
    // Simple default constructor
    Array(int size = 0) : ptr(new int[size]),size(size) {
    }

    int getSize() const { return size; };

    Array& operator=(const Array& rhs);
};

Array& Array::operator=(const Array& rhs)
{
    // Delete any previous allocation
    delete[] ptr;

    ptr = new int[rhs.size];
    size = rhs.size;
    
    for( int i = 0; i < size; i++ )
        ptr[i] = rhs.ptr[i];
        
    return *this;
}

int main()
{
    Array a(5);
    Array b;

    std::cout << "a size=" << a.getSize() << std::endl;

    b = a;

    std::cout << "b size=" << b.getSize() << std::endl;
}

请记住,它被称为operator=作为一个单词,而不是operator =全部隔开。语法无关紧要,但是程序员会以完全不同的方式进行可视化解析。

请注意,这与惯用的C ++有很长的路要走,例如使用size_t更适合“ size”类型的参数,但是您需要一长串的东西来学习去。

,

在谈论operator=之前,我们需要认识到该类已从根本上被破坏:它没有有效的构造函数,并且违反了rule of three,因此没有管理其资源。正确。

之后这两个问题已经解决,(但实际上只有之后!),我们可以转向operator=的实现。首先,请说明您的三点:

我可以观察到的第一件事是size的值尚未定义。因此会出现错误。

该类具有正常工作的构造函数后,size将具有定义的值。

size是私有的,因此我不能从main为其分配值,但这是赋值运算符的参数。在哪里分配值?

在构造函数中。

我尝试在=运算符的定义内分配rhs.size的值,但随后引发分段错误。为什么?

您如何分配

?您尝试赋予它什么价值?由于rhsconst&(应该是!),因此您不能为其成员分配—这将导致编译时错误,而不是分段故障。实际上,rhs的大小是函数前提的一部分。不能修改它(因此使用const&)。

以下是该功能有误的其他地方:

  1. 它不能防止自我分配(如果this == &rhs会怎样?)。
  2. 它不会取消分配ptr中先前分配的内存。