如何正确实现动态Matrix的复制构造函数?

时间:2017-09-29 19:52:45

标签: c++ pointers copy-constructor

我有一个Matrix(Matriz)类实现如下:

部首:

#ifndef MATRIZ_H
#define MATRIZ_H


class Matriz
{
public:
    Matriz(unsigned int nL, unsigned int nC);
    ~Matriz();
    Matriz& operator+=(const Matriz &ptr);
    const Matriz operator+(const Matriz &ptr) const;
    Matriz* subtracaoMatriz(Matriz *m);
    Matriz* multiplicacaoMatriz(Matriz *m);
    void inserirMatriz();
    void imprimirMatriz();
    int verificaOperacao(const Matriz& ptr);
    Matriz& operator-=(const Matriz &ptr);
    const Matriz operator-(const Matriz &ptr) const;
    const Matriz operator*(const Matriz &ptr) const;

protected:

private:
    unsigned int nLinhas;
    unsigned int nColunas;
    int** matrix;
    int verificaOperacao(Matriz *m); //0 -> cannot make the operation; 1 -> OK for product; 2 -> OK for sum;

};

#endif // MATRIZ_H

实现:

#include "Matriz.h"
#include <iostream>

using namespace std;

Matriz::Matriz(unsigned int nL, unsigned int nC)
{
    this->nLinhas = nL;
    this->nColunas = nC;
    this->matrix = new int*[nLinhas];
    for (unsigned int i = 0; i < nLinhas; ++i)
        this->matrix[i] = new int[nColunas];
    for(unsigned int i = 0; i < nLinhas; i++)
        for(unsigned int j = 0; j < nColunas; j++)
            this->matrix[i][j] = 0;
}

Matriz::~Matriz()
{
    //dtor
}

int Matriz::verificaOperacao(Matriz *m)
{
    if((this->nLinhas == m->nLinhas) && (this->nColunas == m->nColunas))
        return 2;
    else if(this->nColunas == m->nLinhas)
        return 1;
    else
        return 0;
}

int Matriz::verificaOperacao(const Matriz& ptr)
{
    if((this->nLinhas == ptr.nLinhas) && (this->nColunas == ptr.nColunas))
        return 2;
    else if(this->nColunas == ptr.nLinhas)
        return 1;
    else
        return 0;
}

Matriz& Matriz::operator+=(const Matriz &ptr) {

    if(this->verificaOperacao(ptr) == 2)
    {
        for(unsigned int i = 0; i < this->nLinhas; i++)
            for(unsigned int j = 0; j < this->nColunas; j++)
                this->matrix[i][j] = this->matrix[i][j] + ptr.matrix[i][j];
        return *this;
    }
    else
        return *this;
}

const Matriz Matriz::operator+(const Matriz &ptr) const {
    Matriz resultado = *this;
    resultado += ptr;
    return resultado;
}


Matriz& Matriz::operator-=(const Matriz &ptr) {
    if(this->verificaOperacao(ptr) == 2)
    {
        for(unsigned int i = 0; i < this->nLinhas; i++)
            for(unsigned int j = 0; j < this->nColunas; j++)
                this->matrix[i][j] = this->matrix[i][j] - ptr.matrix[i][j];
        return *this;
    }
    else
        return *this;
}

const Matriz Matriz::operator-(const Matriz &ptr) const {
    Matriz resultado = *this;
    resultado -= ptr;
    return resultado;
}

const Matriz Matriz::operator*(const Matriz &ptr) const {
    Matriz *resultado = new Matriz(this->nLinhas, ptr.nColunas);
    for(unsigned i = 0; i < this->nLinhas; i++)
    {
        for(unsigned j = 0; j < ptr.nColunas; j++)
            for(unsigned int aux = 0; aux < ptr.nColunas; aux++)
                resultado->matrix[i][j] += this->matrix[i][aux] * ptr.matrix[aux][j];
    }
    return *resultado;
}

void Matriz::inserirMatriz()
{
    for(unsigned int i = 0; i < this->nLinhas; i++)
        for(unsigned int j = 0; j < this->nColunas; j++)
            cin >> this->matrix[i][j];
}

void Matriz::imprimirMatriz()
{

    for(unsigned int i = 0; i < this->nLinhas; i++) {
        for(unsigned int j = 0; j < this->nColunas; j++)
            cout << this->matrix[i][j] << "\t";
        cout << endl;
    }
}

主:

#include <iostream>
#include "Matriz.h"

using namespace std;

int main()
{
    Matriz *m1 = new Matriz(2, 2);
    Matriz *m2 = new Matriz(2, 2);
    m1->inserirMatriz();
    m2->inserirMatriz();
    cout << "Matrix 1:" << endl;
    m1->imprimirMatriz();
    cout << "Matrix 2:" << endl;
    m2->imprimirMatriz();
    Matriz m3 = *m1 + *m2;
    cout << "The sum is: " << endl;
    m3.imprimirMatriz();
    cout << "The subtraction is: " << endl;
    Matriz m4 = *m1 - *m2;
    m4.imprimirMatriz();
    cout << "The product is: " << endl;
    Matriz m5 = *m1 * *m2;
    m5.imprimirMatriz();
    ///HERE LIES THE PROBLEM
    m2 = m1;
    cout << "m2 = m1" << endl;
    cout << "m2:" << endl;
    m2->imprimirMatriz();
    cout << "*m1 += *m2" << endl;
    cout << "m2:" << endl;
    *m1 += *m2;
    m2->imprimirMatriz();

    delete m1;
    delete m2;
    return 0;
}

我认为问题是由默认的复制构造函数引起的,但是我试图实现一个没有成功。

1 个答案:

答案 0 :(得分:-1)

实现复制构造函数有两种方法:

方法1

使用std::vector而不是动态内存,这种方法消除了对自定义复制构造函数的需要,并消除了内存泄漏的风险,请参阅here。我不会重写你的代码,而是做一些简单的事情来说明这一点:

// Header file
#include <vector>

class Matriz
{
  ...
  private:
    std::vector<std::vector<int>> matrix;
}

// CPP file
Matriz::Matriz(unsigned int nL, unsigned int nC)
{
  matrix.resize(nL, std::vector<int>(nC, 0));

  // You can now access items with matrix[x][y].
}

这种带向量的方法很有效,因为当你想要复制Matriz类时,将自动调用vector的副本构造函数。这一切都是为你完成的。

方法2

如果您仍想使用动态内存,则需要实现深层复制构造函数:

//Header file.
class Matriz
{
  ...
  Matriz(const Matriz& m);
}

// CPP file
Matriz::~Matriz() { delete[] matrix; } // DO NOT FORGET THIS!!!

Matriz::Matriz(const Matriz& m)
{
  delete[] matrix;

  // Create the dynamic memory.
  int** matrix = new int*[m.nLinhas];
  for(int i = 0; i < m.nLinhas; ++i)
    matrix[i] = new int[nColunas];

  nLinhas = m.nLinhas;
  nColunas = m.Colunas;

  // Copy over the data.
  for(int l = 0; l < nLinhas; l++)
  {
    for(int c = 0; c < nColunas; c++)
    {
      matrix[l][c] = m.matrix[l][c];
    }
  }
}

您可以对赋值运算符operator=执行相同的概念。如果可以,我建议使用vector,这将消除任何可能的泄漏问题,并且鉴于您正在做的事情,不存在任何速度损失问题。