3

I just want to overload operator with matrix, but I have a problem when I use it. The program can get through operator function but have a problem with this line tong = mt1+mt2 the same problem with line tich = mt1*mt2. I can't understand why. Please help me. Thanks you so much for your help.

#include <stdio.h>
#include <conio.h>
#include <iostream>

using namespace std;

class MT{
private:
int row;
int col;
int **matrix;
public:
MT(){
    row = 0;
    col = 0;
    matrix = NULL;
}
MT(int row1, int col1){
    row = row1;
    col = col1;
    matrix = new int *[row];
    for (int i = 0; i<row; i++)
        matrix[i] = new int[col];
}
~MT(){
    for (int i = 0; i<row; i++)
        delete []matrix[i];
    delete []matrix;
}
friend ostream& operator<< (ostream &os,const MT &mt){
    for (int i = 0; i<mt.row; i++){
        for (int j = 0; j<mt.col; j++)
            cout << mt.matrix[i][j]<<"   ";
        cout <<endl;
    }
    return os;
}
friend istream& operator>> (istream &is,MT &mt){
    int row1, col1;
    cout <<"\n Nhap so row ma tran:   "; fflush(stdin); cin >> row1;
    cout <<"\n Nhap so col ma tran:    "; fflush(stdin); cin >> col1;
    mt.row = row1;
    mt.col = col1;
    mt.matrix = new int *[row1];
    for (int i = 0; i<row1; i++)
        mt.matrix[i] = new int[col1];
    for (int i = 0; i < row1; i++)
        for (int j = 0; j< col1; j++)
            is >> mt.matrix[i][j];
    return is;
}
MT operator+(MT &mt){
    MT temp(mt.row,mt.col);
    if ((this->row != mt.row) || (this->col != mt.col)){
        cout <<"\n Khong the thuc hien phep cong!";
        return temp;
    }
    else{
        for (int i = 0; i < row; i++)
            for (int j = 0; j < col; j++)
                temp.matrix[i][j] = this->matrix[i][j] + mt.matrix[i][j];
        return temp;
    }
}
MT operator-(MT &mt){
    MT temp(mt.row,mt.col);
    if ((this->row != mt.row) || (this->col != mt.col)){
        cout <<"\n Khong the thuc hien phep tru!";
        return temp;
    }
    else{
        for (int i = 0; i < row; i++)
            for (int j = 0; j < col; j++)
                temp.matrix[i][j] = this->matrix[i][j] - mt.matrix[i][j];
        return temp;
    }
}
MT operator*(MT &mt){
    MT temp(this->row, mt.col);
    if (this->row != mt.col){
        cout <<"\n Khong the thuc hien phep nhan.";
        return temp;
    }
    else{
        for (int i = 0; i < this->row; i++)
            for (int j = 0; j < mt.col; j++)
            {
                temp.matrix[i][j] = 0;
                for (int k = 0; k<this->row; i++)
                    temp.matrix[i][j] += this->matrix[i][k]*mt.matrix[k][j];
            }
            return temp;
    }
}
MT operator=(MT &mt){
    row = mt.row;
    col = mt.col;
    this->matrix = new int *[row];
    for (int i=0; i<row; i++)
        this->matrix[i] = new int[col];
    for (int i =0; i<row; i++)
        for (int j = 0; j<col; j++)
            this->matrix[i][j] = mt.matrix[i][j];
    return mt;
}
};

void main()
{
MT mt1,mt2,tong,tich;
cin>>mt1;
cin>>mt2;
tong = mt1+mt2;
cout <<tong;
tich = mt1*mt2;
cout <<tich;
_getch();
}
Ruồi Trâu
  • 91
  • 2
  • 10
  • You haven't provided a copy (or move) constructor. When you return an instance of an MT object, the return value is copied, then the one inside the function is destroyed. Without a copy/move ctor, you're getting two objects with pointers to the same data. When the local one local to the function is destroyed, the memory is freed, and the copy that's returned to the caller now contains dangling pointers. – Jerry Coffin Apr 21 '15 at 02:23
  • @vsoftco: The error is that he's trying to implement remote ownership without a copy ctor. – Jerry Coffin Apr 21 '15 at 02:25
  • @JerryCoffin true, there are also syntactic errors, as in the line `tich = mt1 * mt2;` OP returns a rvalue, then tries to bind it to a non-const reference... – vsoftco Apr 21 '15 at 02:27
  • I suggest you read http://stackoverflow.com/questions/4421706/operator-overloading for an excellent intro to operator overloading. Unfortunately you have way to many issues in your code right now. – vsoftco Apr 21 '15 at 02:29
  • So the solution is providing a copy constructor, isn't it? but it won't be the same as other normal operator? – Ruồi Trâu Apr 21 '15 at 02:31

1 Answers1

2

The rule of three (aka law of the big three, etc.) says that if your class implements any one of a copy constructor, copy assignment operator, or destructor, you nearly always need to implement all three of them. Typically (as in this case) you realize you need the dtor to free the memory you've allocated. In that case, you nearly always need a copy constructor and a copy assignment operator.

The rule of 5 is an update of that for C++11, where you add move assignment and move construction along with the previous three.

The rule of zero says you should usually avoid all of the above, and use some existing class to actually manage the memory, instead of trying to do it on your own. Obvious options are std::shared_ptr and std::unique_ptr, or using an existing container such as std::vector or std::deque.

In your case, a copy constructor would probably look at least roughly like this:

MT(MT const &r){
    row = r.row;
    col = r.col;
    matrix = new int *[row];
    for (int i = 0; i<row; i++) {
        matrix[i] = new int[col];
        for (int j=0; j<col; j++)
            matrix[i][j] = r.matrix[i][j];
    }
}

A move ctor would look something like this:

MT (MT &&r) {
     row=r.row;
     col=r.col;
     matrix = r.matrix;
     r.row=0;
     r.col=0;
     r.matrix = nullptr;
}

Then you'll need to do roughly the same for move assignment (well, both move-assignment and move construction are optional, but strongly recommended if you're going to implement something like this).

Also note that your copy assignment operator should normally take its operand by const reference, and return a non-const reference (which should almost always be return *this;).

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • It means that no way to use this line "tong = mt1+mt2", doesn't it? I just want to overload a operator like the others? – Ruồi Trâu Apr 21 '15 at 02:41
  • @RuồiTrâu: I'm not sure what you mean. Yes, with a proper copy ctor (or move ctor) you can do something like `tong = mt1+mt2;`, but you need to provide the proper ctor, not an operator overload to do it. – Jerry Coffin Apr 21 '15 at 02:44
  • I understood. Thank you so much and sorry for my English. You're a good guy. :) – Ruồi Trâu Apr 21 '15 at 02:50