2011-09-18 78 views
3

我想写一个矩阵类,它将能够找到逆,伴随等。任何次序的方阵。 构造函数初始化n阶单位矩阵(传递给它)。矩阵类运算符重载,析构函数问题

class Matrix 
{ 
int** elements; 
int order; 

public: 
Matrix& operator=(const Matrix& second_inp) 
{ 
    if(this->order!=second_inp.order) 
     cout<<"The matrix cannot be assigned!!!\n"<<this->order<<"\n"<<second_inp.order; 

    else 
    { 
     for(int i=0;i<this->order;i++) 
      for(int j=0;j<this->order;j++) 
       this->elements[i][j] = second_inp.elements[i][j]; 

    } 

    return *this; 
} 

Matrix operator*(const Matrix& a)const 
{ 
    Matrix c(a.order); 

    for(int i=0;i<c.order;i++)      
     for(int j=0;j<c.order;j++) 
      c.elements[i][j]=0; 

    if (this->order!=a.order) 
    { 
     cout<<"The 2 Matrices cannot be multiplied!!!\n"; 
     return Matrix(); 
    } 

    else 
    { 
     for(int i=0;i<a.order;i++) 
      for(int j=0;j<a.order;j++) 
       for(int k=0;k<a.order;k++) 
        c.elements[i][j] += (this->elements[i][k])*(a.elements[k][j]); 

     return c; 
    } 
} 
}; 

~Matrix() 
{ 
    for(int i=0;i<this->order;i++) 
     delete[] *(elements+i); 
    delete[] elements; 
    elements=nullptr; 
} 

如果我使用这个类来运行下面的代码:

Matrix exp1(2),exp2(2),exp3(2); 
exp1.get_matrix(); 
exp3=exp1*exp2; 
exp3.show_matrix(); 

我得到一个运行时错误,在调试时我发现,乘法(EXP1 * EXP2)后=运算符如果*运算符的结果不能访问数据。

但是,如果我要在main()的末尾使用像这样的手动析构函数来释放所有分配的内存,程序将正常工作。

void destroctor() 
{ 
    for(int i=0;i<order;i++) 
    delete[] *(elements+i); 
    delete[] elements; 
} 

操作如何,我可以编辑的析构函数或重载来解决这个问题?

我使用的构造函数:

Matrix(int inp_order):order(inp_order) 
{ 
    elements=new int*[order]; 

    for(int i=0;i<order;i++) 
     *(elements+i)=new int[order]; 

    for(int i=0;i<order;i++) 
     for(int j=0;j<order;j++) 
     { 
      if (i==j) 
       *(*(elements+j)+i)=1; 
      else 
       *(*(elements+j)+i)=0; 
     } 
} 
+4

遵循三的规则。 –

+0

您的代码中是否也包含“元素”的分配(而不仅仅是在问题中)? – eran

+0

在实际的代码中没有分配不会丢失。我在该问题中添加了构造函数。 – Likhit

回答

3

由于您尚未发布您的构造函数,因此很难分辨出什么问题。

exp3=exp1*exp2;很多事情发生了:

首先一个新的矩阵C是运营商*函数构造。然后return c;语句调用复制构造函数,然后调用析构函数。在那之后调用operator =,并在那之后重新构造临时矩阵的析构函数。

我认为会发生什么是您正在使用默认复制构造函数,它不会进行深层复制。这样,在return c时被调用的析构函数删除了矩阵之间仍然共享的数据。

+0

它可能实际上缺少一个拷贝构造函数。 – Shautieh

+0

是的,我没有使用复制构造函数。我认为'operator ='的作用与复制构造函数相同,因此将直接调用。谢谢。 – Likhit

+0

@Likhit:如果你没有提供拷贝构造函数,编译器会为你提供一个拷贝构造函数。在这种情况下,它只是复制指针值'elements'。当您需要始终在复制构造函数和赋值运算符重载中进行“深层复制”时,这是一个“浅层副本”。 –

0

我得到一个运行时错误,在调试时我发现,乘法(EXP1 * EXP2)后=运营商无法访问数据如果*运算符的结果。

你没告诉我们你的构造,所以没有办法告诉你为什么要得到这个错误。

我怀疑原因是你没有分配需要的内存来容纳你的矩阵。您将其声明为int**,因此您需要分配一个int*指针数组,并且对于您需要分配int数组的每个数组。

编辑
当我打字时,你为你的构造函数发布了代码。

您没有从您的超载operator*中返回值,并且您没有复制构造函数(规则为三)。

您是否启用了编译器警告?任何值得使用盐的编译器都会抱怨操作符重载中缺少返回语句。

+0

我很抱歉,但我在'operator *'函数中返回了临时矩阵(c),它出现在'else'语句中。 – Likhit

+0

我没有看到那个回报。更糟糕的是, C++有例外。使用它们。或者调用'exit()'。当你有这样严重的错误时,不要返回一个虚假的值。更好的做法是让这个问题成为编译时错误,但这需要使用模板。 –

0

您尚未定义复制构造函数,因此编译器会为您生成一个。此构造函数将被调用以将operator*(const & Matrix a)的返回值复制到结果中。

由于生成的副本构造函数只执行浅层成员副本,因此不会分配新的元素数组,因此会出错。