【问题标题】:Matrix class operator overloading,destructor problem矩阵类运算符重载、析构问题
【发布时间】:2011-11-19 15:10:26
【问题描述】:

我正在尝试编写一个矩阵类,它能够找到逆矩阵、伴随矩阵等。任意阶的方阵。 构造函数初始化 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)之后,如果 *operator 的结果,=operator 无法访问数据。

但是,如果我在 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;
        }
}

【问题讨论】:

  • 您的代码中是否也缺少elements 的分配(而不仅仅是问题中)?
  • 不,实际代码中没有丢失分配。我在问题中添加了构造函数。
  • 是的,我也尝试通过引用返回,但它只是返回一堆警告,说我正在引用已被删除的内存。
  • @Likhit:如果你想要一个完美的程序,你不应该留下任何警告:)
  • 向我们展示你的复制构造函数(如果你没有,那就是你的错误)。

标签: c++ matrix operator-overloading destructor


【解决方案1】:

我得到一个运行时错误,在调试时我发现,在乘法(exp1*exp2)之后,如果 *operator 的结果,=operator 无法访问数据。

您没有向我们展示您的构造函数,因此无法说明您收到此错误的原因。

我怀疑原因是您没有分配包含矩阵所需的内存。您将其声明为int**,因此您需要分配一个int* 指针数组,并为每个指针分配一个int 数组。

编辑
在我输入此内容时,您发布了构造函数的代码。

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

您是否启用了编译器警告?任何称职的编译器都会抱怨运算符重载中缺少返回语句。

【讨论】:

  • 很抱歉,我在“operator*”函数中返回临时矩阵(c),它出现在“else”语句中。
  • 我没有看到那个回报。在某种程度上,甚至更糟。 C++ 有例外。使用它们。或致电exit()。当您遇到此类严重错误时,请勿返回虚假值。更好的是使这个问题成为编译时错误,但这需要使用模板。
【解决方案2】:

很难判断出了什么问题,因为你还没有发布你的构造函数。

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

首先在 operator* 函数中构造一个新矩阵 c。然后return c;语句调用复制构造函数,然后调用析构函数。之后调用 operator= ,然后再次调用临时矩阵的析构函数。

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

【讨论】:

  • 它可能确实缺少复制构造函数。
  • 是的,我没有使用复制构造函数。我假设 'operator=' 的工作方式与复制构造函数相同,因此将被直接调用。谢谢。
  • @Likhit:如果您不提供复制构造函数,编译器将为您提供一个。在这种情况下,它只是复制指针值elements。当您需要始终在复制构造函数和赋值运算符重载中进行“深拷贝”时,这是一个“浅拷贝”。
【解决方案3】:

你还没有定义一个拷贝构造函数,所以编译器会为你生成一个。将调用此构造函数,以便将operator*(const &amp; Matrix a) 的返回值复制到结果中。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-04
    • 2015-07-29
    • 1970-01-01
    • 2020-12-17
    • 1970-01-01
    • 1970-01-01
    • 2016-02-16
    • 1970-01-01
    相关资源
    最近更新 更多