Перегрузка операторов матричного класса, проблема деструктора - PullRequest
3 голосов
/ 18 сентября 2011

Я пытался написать матричный класс, который мог бы найти обратный, сопряженный и т. Д. квадратной матрицы любого порядка. Конструктор инициализирует единичную матрицу порядка 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;
        }
}

Ответы [ 3 ]

3 голосов
/ 18 сентября 2011

Трудно сказать, что идет не так, потому что вы не опубликовали свои конструкторы.

В exp3=exp1*exp2; происходит много вещей:

Сначала в функции оператора * строится новая матрица c. Тогда return c; оператор вызывает конструктор копирования, а затем деструктор. После этого вызывается оператор = и после этого снова деструктор для временной матрицы.

Мне кажется, что вы используете конструктор копирования по умолчанию, который не делает глубокую копию. Таким образом, деструктор, вызываемый во время return c, удаляет данные, которые все еще были разделены между матрицами.

0 голосов
/ 18 сентября 2011

Вы не определили конструктор копирования, поэтому компилятор сгенерирует его для вас. Этот конструктор будет вызван, чтобы скопировать возвращаемое значение operator*(const & Matrix a) в результат.

Поскольку сгенерированный конструктор копирования выполняет только поверхностное копирование для каждого элемента, он не будет выделять новый массив элементов, поэтому возникает ошибка.

0 голосов
/ 18 сентября 2011

Я получаю ошибку во время выполнения, при отладке я обнаружил, что после умножения (exp1 * exp2) оператор = не смог получить доступ к данным, если результат оператора *.

Вы не показывали нам свой конструктор, поэтому невозможно сказать, почему вы получаете эти ошибки.

Я подозреваю, что причина в том, что вы не выделяете память, необходимую для хранения вашей матрицы. Вы объявили его как int**, поэтому вам нужно выделить массив из int* указателей, а для каждого из них вам нужно выделить массив int.

Редактировать
Пока я набирал это, вы разместили код для вашего конструктора.

Вы не возвращаете значение из-за перегрузки operator*, и у вас нет конструктора копирования (правило трех).

У вас включены предупреждения компилятора? Любой компилятор, достойный его соли, пожаловался бы на отсутствующий оператор return в перегрузке оператора.

...