[英]Copy constructor and operator= for a dynamic array inside a class
我需要一些帮助来为我的类中的动态数组实现复制构造函数和operator =。 我目前不允许使用向量
这是mye代码:类:
class Matrix{
private:
int rows;
int columns;
double* matrix;
public:
Matrix();
explicit Matrix(int N);
Matrix(int M, int N);
void setValue(int M, int N, double value);
double getValue(int M, int N);
bool isValid() const;
int getRows();
int getColumns();
~Matrix();
friend ostream& operator<<(ostream &out, Matrix&matrix1);
};
而我的代码:
Matrix::Matrix(){
matrix = NULL;
}
Matrix::Matrix(int N){
matrix = new double[N * N];
rows = N;
columns = N;
for(int i = 0; i < N; i++){
for(int j = 0; j < N; j++){
if(i==j)
matrix[i * N + j] = 1;
else
matrix[i * N + j] = 0;
}
}
}
Matrix::Matrix(int M, int N){
matrix = new double[M * N];
rows = M;
columns = N;
for(int i = 0; i < M; i++){
for(int j = 0; j < N; j++)
matrix[i * N + j] = 0;
}
}
Matrix::~Matrix(){
delete [] matrix;
}
void Matrix::setValue(int M, int N, double value){
matrix[M * columns + N] = value;
}
double Matrix::getValue(int M, int N){
return matrix[M * columns + N];
}
bool Matrix::isValid() const{
if(matrix==NULL)
return false;
else
return true;
}
int Matrix::getRows(){
return rows;
}
int Matrix::getColumns(){
return columns;
}
ostream& operator<<(ostream &out, Matrix&matrix1){
if(matrix1.isValid())
for(int i = 0; i < matrix1.getRows(); i++){
for(int j = 0; j < matrix1.getColumns(); j++)
out << matrix1.getValue(i,j) << "\t";
out << endl;
}
else
out << "Matrisen er ikke gyldig."; //the matrix is not valid
return out;
}
这样的事情行吗?
Matrix &operator=(const Matrix &m) {*(this->matrix) = *(m.matrix);}
Matrix(const Matrix &rhs) : matrix(0) {
this->matrix = new double();
*(this->matrix) = *(rhs.matrix);
}
我也将重载运算符+ =和+。 我尝试将其实现为:
const Matrix operator+=(Matrix matrix1, Matrix matrix2){
if(!matrix1.isValid() || !matrix2.isValid()){
cout << "En av matrisene er ugyldig"; //one of the matrices are invalid
return Matrix::Matrix(); //returning a NULL matrix
}
else{
if(matrix1.getColumns()==matrix2.getColumns() && matrix1.getRows()==matrix2.getRows()){
Matrix temp(matrix1.getRows(), matrix1.getColumns());
for(int i = 0; i < matrix1.getRows(); i++){
for(int j = 0; j < matrix1.getColumns(); j++)
temp.setValue(i,j,(matrix1.getValue(i,j) + matrix2.getValue(i,j)));
}
return temp;
}
else{
cout << "Matrisene har ikke samme dimensjon"; //the matrices does not have the same dimensions
return Matrix::Matrix();
}
}
}
const Matrix operator+(Matrix matrix1, Matrix matrix2){
return matrix1 += matrix2;
}
这样的事情行吗? 将操作员作为班级的一部分,班级的朋友还是仅在班级之外重载会更好吗?
任何帮助都适用。
为什么删除另一个问题? 我希望这只是一个错误:(请参阅最后的编辑)
是的,您的代码甚至设计中都有很多问题。
只是给你一个想法:
您的矩阵没有复制构造函数(或移动),也没有“ =
”。 他们是:
Matrix(const Matrix &m);
和(移动构造函数):
Matrix(Matrix &&m);
和
Matrix& operator=( const Matrix &m);
Matrix& operator=( Matrix &&m);
如果您没有定义这些特殊功能,则编译器将为您定义它。 但是它们显然只会起作用。 程序编译但工作不正确( 浅层复制与深层复制问题 ,并通过值或引用传递 )。 我想您在构造函数中使用new
来构建matrix
私有数组。 然后在析构函数中delete[]matrix
。 每次通过值传递Matrix
,都会使用编译器生成的复制构造函数进行复制,只复制Matrix
成员的值,从而复制指针matrix
的值,而不复制数组。 在通话结束时,此本地副本将被销毁,原始矩阵将被删除!! 这只是许多问题之一。 您足够坐下,多读一本垃圾,然后再试一次。 “简单”修复程序可能会取代
double *matrix;
通过
std::vector<double> matrix;
现在,编译器生成的函数将更好地工作。
是的,如果要在Matrix
使用[]
,则需要对其进行定义。 +=
是一个二元运算符,带有一个参数(左边始终是this
,指向调用它的对象的指针)。 在这里,您只需要带有两个参数的免费+()
或带有一个参数的成员+()
。 希望这对您有所帮助。 再问一遍。
编辑:这是否可以作为operator=
?
Matrix &operator=(const Matrix &m) {*matrix = *(m.matrix);}
不,这只会复制第一个双精度数。 您将需要在Entery数组上循环并复制每个元素。 首先,您需要确保矩阵的大小兼容。 (如果使用vector
matrix=m.matrix
则可以使用。)。 您的副本构造函数的修复方法可能是:
Matrix::Matrix(const Matrix &m): rows (m.rows),
columns (m.columns),
matrix (new double[rows* columns])
{
for(int i = 0; i < rows; i++)
for(int j = 0; j < columns; j++)
matrix[i * columns + j] = m.matrix[i * columns + j];
}
并移动:
Matrix::Matrix( Matrix &&m): rows (m.rows),
columns (m.columns),
matrix (m.matrix)
{
m.matrix=nullptr;
m.rows= m.columns=0;
}
当您不关心原始值时,例如临时对象的情况,此举可以大大提高应对矩阵的效率。 在这种情况下,您不需要迭代复制每个数组元素:您只需窃取整个数组。 这样做的好处是,在大多数情况下,编译器将为您“自动”选择正确的变体(复制或移动)。
Matrix &operator=(const Matrix &m) {*(this->matrix) = *(m.matrix);}
这只会将lhs矩阵的第一个元素分配为与rhs'矩阵的第一个元素相同。 最重要的是,这将要求两个矩阵都使用相同数量的行和列进行初始化。 您可以使用memcpy或循环来分配所有元素。
Matrix(const Matrix &rhs) : matrix(0) {
this->matrix = new double();
*(this->matrix) = *(rhs.matrix);
}
这将失败,因为您没有为新构造的实例的矩阵成员分配足够的内存(除非另一个矩阵是1x1矩阵)。 假设矩阵以行优先顺序存储,则它应如下所示:
Matrix(const Matrix &rhs) : matrix(0), rows(rhs.rows), columns(rhs.columns) {
this->matrix = new double[rows * columns];
for (size_t r = 0; r < rows; r++) {
for (size_t c = 0; c < columsn; c++) {
this->matrix[r * columns + c] = rhs.matrix[r * columns + c];
}
}
}
编辑:只是为了确保,这就是我要做赋值运算符的方法:
Matrix &operator=(const Matrix &m) {
if (rows * columns != m.rows * m.columns) {
delete [] this->matrix;
this->matrix = new double[m.rows * m.columns];
}
rows = m.rows;
columns = m.columns;
for (size_t r = 0; r < rows; r++) {
for (size_t c = 0; c < columsn; c++) {
this->matrix[r * columns + c] = m.matrix[r * columns + c];
}
}
return *this;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.