Перегрузка операторов. Указатель на возвращаемое значение

Только начал изучать перегрузку операторов и столкнулся со след. проблемой. В программе выполняется умножение матрицы на целое число, перегружал два оператора * и =. Судя по всему, проблема в доступе к памяти моей матрицы. Также, если создаю матрицу B через конструктор по умолчанию, то итоговое значение матриц пустое, если создаю матрицу B через конструктор с двумя переменными, то он указывает на проблемное место - 86 строка. Также слышал, что от friend стоит лучше избавиться, но я не знаю как именно.

#include <iostream>
using namespace std;

class Matrix {

private:
    int a, b;
    int** arr;

public:
    Matrix()
    {
        this->a = 0;
        this->b = 0;
        this->arr = 0;
    }

    Matrix(int a, int b) {
        this->a = a; this->b = b;
        Create();
    }
    
    ~Matrix() {
        Delete();
    }

    void Create() {
        arr = new int* [b];

        for (int i = 0; i < b; i++)
            arr[i] = new int[a];
    }

    int Get_a()
    {
        return a;
    };

    int Get_b()
    {
        return b;
    };

    void Set_Elements() {
        for (int i = 0; i < a; i++) {
            for (int j = 0; j < b; j++)
                cin >> arr[i][j];
        }
    }

    void Delete() {
        for (int i = 0; i < b; i++) {
            delete arr[i];
        }
        delete[] arr;
    }

    void Print() {
        for (int i = 0; i < a; i++) {
            for (int j = 0; j < b; j++)
                cout << arr[i][j] << ' ';
            cout << endl;
        }
    }

    friend Matrix& operator * (Matrix& A, int m) 
    {
        int a1 = A.Get_a();
        int b1 = A.Get_b();
        Matrix temp(a1, b1);

        for (int i = 0; i < a1; i++) {
            for (int j = 0; j < b1; j++) {
                temp.arr[i][j] = A.arr[i][j] * m;
            }
        }
        return temp;
    }
    
    void Matrix_Copy(Matrix& C) {
        Delete();
        Create();

        for (int i = 0; i < a; i++) {
            for (int j = 0; j < b; j++)
                arr[i][j] = C.arr[i][j];
        }
    }

    Matrix& operator = (Matrix& A)
    {
        Matrix_Copy(A);
        return *this;
    }

    friend ostream& operator << (ostream& ostr, Matrix& A)
    {
        A.Print();
        return (ostr);
    }

    friend istream& operator >> (istream& in, Matrix& A)
    {
        A.Set_Elements();
        return (in);
    }

};


int main() {
    int m = 2;
    Matrix A(3, 3);

    cin >> A;

    Matrix B;
    cout << "A = " << endl;
    cout << A;
    cout << "A*m = B" << endl;
    
    
    B = A * m;
    cout << B;

    return 0;
}

Ответы (1 шт):

Автор решения: Harry

Словом, с учетом сказанного в комментарии я бы делал так — попробуйте разобраться, что и почему переделано. Может, в этот полночный час что и упустил, типа проверок, не пустая ли матрица и т.п...

#include <iostream>
#include <iomanip>

using namespace std;

class Matrix
{
private:
    size_t rows_, cols_;
    int ** arr;

    void swap(Matrix& m)
    {
        size_t t = rows_; rows_ = m.rows_; m.rows_ = t;
        t = cols_; cols_ = m.cols_; m.cols_ = t;
        int ** p = arr; arr = m.arr; m.arr = p;
    }

public:
    Matrix(size_t rows = 0, size_t cols = 0):rows_(rows),cols_(cols),arr(nullptr)
    {
        if (rows_ && cols_)
        {
            arr = new int*[rows_];
            for (size_t i = 0; i < rows_; i++)
                arr[i] = new int[cols_];
        }
    }

    Matrix(const Matrix& m):rows_(m.rows_),cols_(m.cols_),arr(nullptr)
    {
        if (rows_ && cols_)
        {
            arr = new int*[rows_];
            for (size_t i = 0; i < rows_; i++)
            {
                arr[i] = new int[cols_];
                for(size_t j = 0; j < cols_; ++j)
                    arr[i][j] = m.arr[i][j];
            }
        }
    }

    Matrix& operator = (const Matrix& m)
    {
        Matrix tmp(m);
        swap(tmp);
        return *this;
    }

    ~Matrix()
    {
        for (size_t i = 0; i < rows_; i++)
            delete arr[i];
        delete[] arr;
    }

    size_t rows() const
    {
        return rows_;
    };

    size_t cols() const
    {
        return cols_;
    };

    int*       operator[](size_t i)       { return arr[i]; }
    const int* operator[](size_t i) const { return arr[i]; }


};

// Нехорошо, так как размеры НЕ читаются
istream& operator >> (istream& in, Matrix& A)
{
    for (size_t i = 0; i < A.rows(); i++)
    {
        for (size_t j = 0; j < A.cols(); j++)
            in >> A[i][j];
    }
    return in;
}

ostream& operator << (ostream& ostr, const Matrix& A)
{
    for (size_t i = 0; i < A.rows(); i++)
    {
        for (size_t j = 0; j < A.cols(); j++)
            cout << setw(5) << A[i][j] << " ";
        cout << endl;
    }
    return ostr;
}

Matrix operator *(const Matrix& A, int m)
{
    Matrix temp(A.rows(), A.cols());
    for (size_t i = 0; i < A.rows(); i++)
    {
        for (size_t j = 0; j < A.cols(); j++)
        {
            temp[i][j] = A[i][j] * m;
        }
    }
    return temp;
}

int main() {
    int m = 2;
    Matrix A(3, 3);

    cin >> A;

    Matrix B;
    cout << "A = " << endl;
    cout << A;
    cout << "A*m = B" << endl;


    B = A * m;
    cout << B;

    return 0;
}
→ Ссылка