【问题标题】:How to overload assignment operator and create copy constructor for 2D Dynamic Arrays?如何重载赋值运算符并为 2D 动态数组创建复制构造函数?
【发布时间】:2020-11-14 21:24:27
【问题描述】:

我有一个包含 bool** 属性的航班。

class Flight {
public:
 int flightNumber;
 int row;
 int seat;
 bool** seatReserv;
 Flight();
 Flight(int fly,int rw,int st);
 ~Flight();
 Flight(const Flight& rightVal);
 Flight& operator=(const Flight& rightVal);
 };

我尝试将我的重载赋值运算符编写如下,但是我意识到即使我更改了我的行和座位属性,我也没有更改二维数组 [行] 和 [座位] 的大小。

Flight& Flight::operator=(const Flight& rightVal){
        if(this != &rightVal){
                for(int i = 0; i < row; i++){
                    delete[] this->seatReserv[i];
                }
                delete [] this->seatReserv;


            flightNumber = rightVal.flightNumber;
            row = rightVal.row;
            seat = rightVal.seat;



            this -> seatReserv = new bool*[row];
            for(int i = 0; i < row; i++){
                seatReserv[i] = new bool[seat];

            }

            for(int i = 0; i < row; i++){
                for(int j = 0; j < seat; j++){
                    seatReserv[i][j] = rightVal.seatReserv[i][j];

                }
            }


        }

        return *this;

        }

此外,我在下面的复制构造函数中遇到了同样的问题,所以问题是如何为我的类编写复制构造函数并重载赋值运算符?

Flight::Flight(const Flight& rightVal){
        flightNumber = rightVal.flightNumber;
        row = rightVal.row;
        seat = rightVal.seat;
        for(int i = 0; i < row; i++){
            for(int j = 0; j < seat; j++){
                seatReserv[i][j] = rightVal.seatReserv[i][j];
            }
        }
    }

编辑:我不能使用向量,这是家庭作业,所以禁止使用向量。

【问题讨论】:

  • 请注意,双指针与二维数组相同。它只指向一个数组或指针,这是一个与二维数组完全不同的动物。后者的行是连续的,而前者不需要。
  • 这个delete[] this-&gt;seatReserv[seat]; 在你的第一个for 循环中闻起来很有趣!我想你的意思是delete[] this-&gt;seatReserv[i];
  • std::vector&lt;bool&gt; 可能会有所帮助(即使它可能是特殊专业)。
  • “我不能使用向量”,所以写你自己的(简化的)版本。
  • 那么理想情况下,Flight 的特殊成员可能会被默认 :-)

标签: c++ multidimensional-array dynamic 2d


【解决方案1】:

这可能会用作复制构造函数:

Flight::Flight(const Flight &rightVal){
    this->flightNumber = rightVal.flightNumber;
    this->row = rightVal.row;
    this->seat = rightVal.seat;
    this->seatReserv = new bool*[row];
    for (int i = 0; i < this->row; i++){
        this->seatReserv[i] = new bool[seat];
        for (int j = 0; j < this->seat; j++){
            this->seatReserv[i][j] = rightVal.seatReserv[i][j];
        }
    }
}

对于 = 运算符,您可能可以使用与上述相同的内容,但不要忘记删除使用析构函数之前的内容(这是为了避免内存泄漏)。

Flight::~Flight(){
    if (seatReserv == nullptr) return; //this means that at the beginning of the class seatReserv should be set to nullptr.

    for (int i = 0; i < this->row; i++){
        delete[] seatReserv[i];
    }
    delete[] seatReserv;
}

我还建议不要使用“二维数组”,而是使用一个布尔序列,长度为row * seat。要在特定位置访问一个,您可以这样做: i * row + j,而不是这个array[i][j]

这在分配和释放时速度更快,并且对 CPU 缓存更有效。

【讨论】:

  • this-&gt;seatReserv = new bool*[row]; 我认为在这一行中存在内存泄漏,因为当我们将其分配给新的指针时,指向指针的 seareserv 指针具有引用,我们不会丢失以前的内存吗?
  • 这只是之前指向其他东西的情况,这就是为什么使用 = 运算符时必须在复制之前使用析构函数。
  • 除非你打算在已经做完事情后使用复制构造函数,否则实例。这种情况下会有内存泄漏,但是在对象已经存在之后谁使用构造函数。
  • 我当前的赋值运算符有什么问题?
  • 也许在一开始。您正在删除而不检查那里是否有任何东西,这会导致未定义的行为。
【解决方案2】:

这个

       this -> seatReserv = new bool*[row];
        for(int i = 0; i < row; i++){
            seatReserv[i] = new bool[i];

        }

应该是这样的

       this -> seatReserv = new bool*[row];
        for(int i = 0; i < row; i++){
            seatReserv[i] = new bool[seat];

        }

小细节很重要。

您的复制构造函数没有为您的二维数组分配任何内存,所以这是个问题。

【讨论】:

  • 我应该写这个还是我可以在不使用这个指针的情况下将 seatReserv 称为 seatReserv 是否重要?
  • 我的复制构造函数和赋值运算符现在正确了吗?
  • 我会说只是测试一下。
猜你喜欢
  • 2014-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-23
  • 1970-01-01
  • 1970-01-01
  • 2011-07-19
  • 1970-01-01
相关资源
最近更新 更多