How to implement a copy constructor for a two-dimensional matrix in C++?

Asked

Viewed 352 times

1

I have the following situation: a class Matriz implemented as follows:

Header:

#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 -> não da para fazer operação; 1 -> OK para multi; 2 -> OK para soma;

};

Implementation:

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

The problem is that in order for the copy to work properly, it is necessary to use a copy constructor. How to implement this constructor to Matriz?

Main:

#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 << "Matriz 1:" << endl;
    m1->imprimirMatriz();
    cout << "Matriz 2:" << endl;
    m2->imprimirMatriz();
    Matriz m3 = *m1 + *m2;
    cout << "A soma é: " << endl;
    m3.imprimirMatriz();
    cout << "A subtração é: " << endl;
    Matriz m4 = *m1 - *m2;
    m4.imprimirMatriz();
    cout << "A multiplicação é: " << endl;
    Matriz m5 = *m1 * *m2;
    m5.imprimirMatriz();
    ///AQUI OCORRE O PROBLEMA 
    m2 = m1;
    cout << "m2 = m1" << endl;
    m2->imprimirMatriz();
    cout << "*m1 += *m2" << endl;
    *m1 += *m2;
    m2->imprimirMatriz();

    delete m1;
    delete m2;
    return 0;
}

1 answer

2


Follows a tested and improved solution able to take advantage of all the power of the overload of C operators++:

Matriz.h

#ifndef MATRIZ_H
#define MATRIZ_H

#include <iostream>

class Matriz
{
    public:
        Matriz(unsigned int nL, unsigned int nC);
        virtual ~Matriz(void);
        Matriz( const Matriz &ptr );
        Matriz& operator=( const Matriz &ptr );

        Matriz& operator+=(const Matriz &ptr );
        const Matriz operator+(const Matriz &ptr) const;
        Matriz& operator-=(const Matriz &ptr);
        const Matriz operator-(const Matriz &ptr) const;
        const Matriz operator*(const Matriz &ptr) const;

        friend std::ostream &operator<<( std::ostream &out, const Matriz& obj );
        friend std::istream &operator>>( std::istream &in, Matriz &obj );

    protected:
        unsigned int nLinhas;
        unsigned int nColunas;
        int** matrix;

    private:
        void inicializar( unsigned int nL, unsigned int nC, int ** m = 0 );
        void finalizar(void);
};

#endif

Matriz.cpp

#include <iostream>
#include <cstring>

#include "Matriz.h"

Matriz::Matriz(unsigned int nL, unsigned int nC){
    this->inicializar( nL, nC );
}

Matriz::~Matriz(void){
    this->finalizar();
}

void Matriz::inicializar( unsigned int nL, unsigned int nC, int ** m ){
    this->matrix = new int*[nL];
    for( unsigned int i = 0; i < nL; ++i ){
        this->matrix[i] = new int[nC];
        if(!m)
            std::memset( this->matrix[i], 0, sizeof(int) * nC );
        else
            std::memcpy( this->matrix[i], m[i], sizeof(int) * nC );
    }
    this->nLinhas = nL;
    this->nColunas = nC;
}

void Matriz::finalizar(void){
    for(unsigned int i = 0; i < this->nLinhas; ++i)
        delete [] this->matrix[i];
    delete [] this->matrix;
}


Matriz::Matriz( const Matriz &ref ){
    this->inicializar( ref.nLinhas, ref.nColunas, ref.matrix );
}

Matriz& Matriz::operator=( const Matriz &ref ){
    for (unsigned int i = 0; i < ref.nLinhas; ++i)
        std::memcpy( this->matrix[i], ref.matrix[i], sizeof(int) * ref.nColunas );
    return *this;
}

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

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

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

Matriz& Matriz::operator-=(const Matriz &ptr) {
    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;
}

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

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


std::ostream &operator<<( std::ostream &out, const Matriz &ref ){
    for(unsigned int i = 0; i < ref.nLinhas; i++) {
        for(unsigned int j = 0; j < ref.nColunas; j++)
            out << ref.matrix[i][j] << "\t";
        out << std::endl;
    }
    return out;
}

std::istream &operator>>( std::istream &in, Matriz &ref ){
    for(unsigned int i = 0; i < ref.nLinhas; i++)
        for(unsigned int j = 0; j < ref.nColunas; j++)
        {
            std::cout << "(" << i << "," << j << "): ";
            in >> ref.matrix[i][j];
        }
    return in;
}

main.cpp

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

using namespace std;

int main( void )
{
    Matriz m1(2, 2);
    Matriz m2(2, 2);

    cin >> m1;
    cin >> m2;

    cout << "Matriz 1:" << endl;
    cout << m1;

    cout << "Matriz 2:" << endl;
    cout << m2;

    cout << "A soma é: " << endl;
    cout << m1 + m2;

    cout << "A subtração é: " << endl;
    cout << m1 - m2;

    cout << "A multiplicação é: " << endl;
    cout << m1 * m2;

    cout << "m2 = m1:" << endl;
    m2 = m1;
    cout << m2;

    cout << "m1 += m2:" << endl;
    m1 += m2;
    cout << m1;

    cout << "m1 -= m2:" << endl;
    m1 -= m2;
    cout << m1;

    return 0;
}

Testing:

./matriz 
(0,0): 2
(0,1): 4
(1,0): 6
(1,1): 8
(0,0): 1
(0,1): 3
(1,0): 5
(1,1): 7
Matriz 1:
2   4   
6   8   
Matriz 2:
1   3   
5   7   
A soma é: 
3   7   
11  15  
A subtração é: 
1   1   
1   1   
A multiplicação é: 
2   12  
30  56  
m2 = m1:
2   4   
6   8   
m1 += m2:
4   8   
12  16  
m1 -= m2:
2   4   
6   8   

Browser other questions tagged

You are not signed in. Login or sign up in order to post.