【问题标题】:c++ copy assignment operator classesc++ 复制赋值运算符类
【发布时间】:2014-01-29 14:34:05
【问题描述】:

我在课堂上遇到了运算符 = 的问题。这是简化的代码:

类:

#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;

}

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

【问题讨论】:

  • 您需要告诉我们出了什么问题。它崩溃了吗?您是否担心内存泄漏?
  • 在 g++ 下编译干净。真正的问题是什么?
  • @πάνταῥεῖ:或者更好的是,零规则。如果您使用std::vector 而不是手动处理数组,则该类将自动分配。
  • @MikeSeymour 通常,提出此类问题的可怜人不允许使用std::string 或其他他们'还没有学过'的东西。

标签: c++ operator-overloading


【解决方案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. 为你的类添加一个析构函数。

** 假设这是您将使用的代码,而不是为学习数组编写的代码:**

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

  2. 您在全局范围内使用using namespace std;。不要这样做,因为它会产生很多问题。

编辑:

更好的代码:

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

【讨论】:

  • 谢谢你的建议,但是我不太会使用vectors你能“转换”我的代码吗?如果我的要求不高...我什至不知道如何编写析构函数...
  • 比如属性变成了:unsigned rows; unsigned cols; std::vector&lt;int&gt; life(rows*cols); std::vector&lt;int&gt; neighborhood(rows*cols);
  • 或unsigned rows; unsigned cols; std::vector&lt;int&gt; life; std::vector&lt;int&gt; neighborhood;
  • 不过我觉得这个问题对像我这样正在学习的人有帮助……谁是投票否决这个帖子的伟人?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-11-21
  • 2020-11-18
  • 1970-01-01
  • 1970-01-01
  • 2013-10-26
  • 2016-05-18
  • 2019-11-17
相关资源
最近更新 更多