重载运算符矩阵,访问冲突读取

时间:2015-04-21 01:59:58

标签: c++ matrix access-violation

我只是想用矩阵重载运算符,但是当我使用它时我遇到了问题。该程序可以通过运算符函数,但该行tong = mt1+mt2遇到与行tich = mt1*mt2相同的问题。我不明白为什么。请帮我。非常感谢你的帮助。

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

1 个答案:

答案 0 :(得分:2)

三规则(也就是三巨头的法则等)说如果你的类实现了复制构造函数,复制赋值运算符或析构函数中的任何一个,那么你几乎总是需要实现它们中的所有三个。通常情况下(如本例所示),您意识到需要dtor来释放已分配的内存。在这种情况下,您几乎总是需要复制构造函数和复制赋值运算符。

规则5是C ++ 11的更新,您可以在其中添加移动分配和移动构造以及前三个。

零规则说你应该通常避免以上所有,并使用一些现有的类来实际管理内存,而不是试图自己做。显而易见的选项包括std::shared_ptrstd::unique_ptr,或使用现有容器,例如std::vectorstd::deque

在您的情况下,复制构造函数可能至少看起来像这样:

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

移动ctor看起来像这样:

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

然后你需要对移动分配做大致相同的事情(好吧,移动分配和移动构造都是可选的,但如果你要实现类似的东西,强烈建议这样做。)

另请注意,您的复制赋值运算符通常应该通过const引用获取其操作数,并返回非const引用(应该几乎始终为return *this;)。