我班上的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 =的类中 我不知道如何将正确的对象数据复制到左对象数据中,我也不确定是否也正确删除...
答案 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;
}
也就是说,您的代码存在许多其他问题:
假设您编写此代码以了解如何在类中操作动态数组:
您正在使用直接管理两个不同分配资源的类。你应该考虑在m1和m2上使用智能指针(出于例外安全)。
实现三个规则:构造函数(你已经有了),复制构造函数(你没有这个)和赋值运算符(你已经有了这个)。
向您的班级添加析构函数。
**假设这是您将使用的代码,并且没有为学习数组编写代码:**
[]使用std::vector
代替m1和m2。这将使您不必执行三和析构函数规则。
您全局使用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); }
};