c ++复制赋值运算符类

时间:2014-01-29 14:34:06

标签: c++ operator-overloading

我班上的operator =有问题。这是简化的代码:

类:

#include <iostream>

using namespace std;

class Mat{

private:

int *m1;
int *m2;
unsigned rows;
unsigned cols;

void write(unsigned r_max, unsigned c_max){
    m1 = new int [r_max*c_max];
    for(unsigned i = 0; i < r_max*c_max; i++){
        m1[i] = i;
    }       
}

public:

Mat():
rows(1), cols(1){
    m1 = new int [1];
    m1[0] = 0;
    m2 = new int [1];
    m2[0] = 0;
}

Mat(unsigned r, unsigned c):
rows(r), cols(c){
    write(rows, cols);
    m2 = new int [rows*cols];
    for(unsigned i = 0; i < rows*cols; i++)
        m2[i] = 0;
}

Mat &operator=(const Mat &w){
    int *new_ptr1 = NULL;
    new_ptr1 = new int [w.rows*w.cols];
    int *new_ptr2 = NULL;
    new_ptr2 = new int [w.rows*w.cols];
    for(unsigned i = 0; i < w.rows*w.cols; i++){
        new_ptr1[i] = w.say_m1(i);
        new_ptr2[i] = w.say_m2(i);
    }
    delete[] w.m1;
    delete[] w.m2;
    m1 = new_ptr1;
    m2 = new_ptr2;
    rows = w.rows;
    cols = w.cols;
    return *this;
}

int say_m1(unsigned i) const{ return m1[i]; }

int say_m2(unsigned i) const{ return m2[i]; }

~Mat(){
    delete[] m1;
    delete[] m2;
}

};

以下是我需要做的主要内容:

#include "Mat.cpp"
#include <iostream>
#include <cstdlib>

using namespace std;

int main(int argc, char **argv){

Mat a;
Mat b(20, 20);
a = b;

return 0;

}

我认为问题出现在我重载operator =的类中 我不知道如何将正确的对象数据复制到左对象数据中,我也不确定是否也正确删除...

1 个答案:

答案 0 :(得分:1)

  

我认为问题出现在我重载运算符的类中=我不知道如何将正确的对象数据复制到左对象数据中,我也不确定是否正确删除...

你没有(正确删除)。

Operator =应该改变*this的值。相反,您删除w.m1和w.m2(其中w是您的参数)。

更正后的代码:

Mat &operator=(const Mat &w){
    int *new_ptr1 = NULL;
    new_ptr1 = new int [w.rows*w.cols];
    int *new_ptr2 = NULL;
    new_ptr2 = new int [w.rows*w.cols];
    for(unsigned i = 0; i < w.rows*w.cols; i++){
        new_ptr1[i] = w.say_m1(i);
        new_ptr2[i] = w.say_m2(i);
    }
    delete[] m1; // <<< HERE
    delete[] m2; // <<< HERE
    m1 = new_ptr1;
    m2 = new_ptr2;
    rows = w.rows;
    cols = w.cols;
    return *this;
}

也就是说,您的代码存在许多其他问题:

假设您编写此代码以了解如何在类中操作动态数组:

  1. 您正在使用直接管理两个不同分配资源的类。你应该考虑在m1和m2上使用智能指针(出于例外安全)。

  2. 实现三个规则:构造函数(你已经有了),复制构造函数(你没有这个)和赋值运算符(你已经有了这个)。

  3. 向您的班级添加析构函数。

  4. **假设这是您将使用的代码,并且没有为学习数组编写代码:**

    1. []使用std::vector代替m1和m2。这将使您不必执行三和析构函数规则。

    2. 您全局使用using namespace std;。不要这样做,因为它会造成很多问题。

    3. 编辑:

      更好的代码:

      #include <iostream>
      #include <vector>
      
      class Mat{
      std::vector<int> life;
          std::vector<int> neighborhood;
      
      public:
      
          // this is unnecessary
          // void write(unsigned r_max, unsigned c_max);  {
      
          Mat() : life(1), meighborhood(1) // fill each with 1 int with default value (0)
          {
          }
      
          Mat(unsigned r, unsigned c)
            : life(r), meighborhood(c) // fill each with r(and c) ints with default value (0)
          {
          }
      
          // ~Mat() became unnecessary: destructors of std::vector will deallocate fine
      
          Mat &operator=(const Mat &w) {
              // create replacements before doing changing any value
              // this way, if you get an exception while creating the data
              // the value in the obhect does not change
              std::vector<int> new_life(w.life);
              std::vector<int> new_neighborhood(w.neighborhood);
      
              life.swap(new_life);
              neighborhood.swap(new_neighborhood);
              return *this;
          }
      
          // use std::vector<int>::at which throws an exception if the index is invalid
          // if you are not interested in the validation of the index
          // return life[i] and neighborhood[i]
          int say_m1(unsigned i) const{ return life.at(i); }
          int say_m2(unsigned i) const{ return neighborhood.at(i); }
      };