Динамическое выделение матрицы с использованием уникальных указателей - PullRequest
0 голосов
/ 29 марта 2020

В упражнении, которое я пытаюсь решить, говорится, что я должен создать динамически распределенную матрицу, используя уникальные указатели, которые разрешают следующие операции:

  1. Matrix a, b;
  2. Matrix c (b);
  3. Матрица d = a;
  4. Матрица e = a + b;

До сих пор я пытался реализовать матрицу ( за исключением добавления), но я не могу обернуть голову, как мне реализовать уникальные указатели в этом примере.


class Matrix
{

public:
    vector<vector<int>> data;

    Matrix() {}

    Matrix(vector<vector<int>> matrix)
    {
        this->data=matrix;
    }


    Matrix (const Matrix& m2)
    {
        this->data=m2.data;

    }
    Matrix& operator= (const Matrix &m2)
    {
        this->data = m2.data;
        return *this;
    }

  void print()
    {
        vector< vector<int> >::iterator row;
        vector<int>::iterator col;
        for (row = data.begin(); row != data.end(); row++)
        {
            for (col = row->begin(); col != row->end(); col++)
            {
                cout<<*col<<" ";
            }
            cout<<endl;
        }
    }

} ;

int main()
{
    vector<vector<int> > matrix(3);
    for ( int i = 0 ; i < 3 ; i++ )
        matrix[i].resize(3);

    Matrix m(matrix);
    m.print();

    Matrix m2(m);
    m2.print();

    Matrix m3;
    m3=m2;
    m3.print();

}


Помощь очень ценится. Приветствия.

1 Ответ

1 голос
/ 29 марта 2020

Единственная практическая проблема, связанная с вашим решением, заключается в том, что вы используете vector из vector с, что может быть немного неэффективно, поскольку существует дополнительный уровень косвенности при доступе к внутреннему vector.

Лучше выделить один vector для хранения всей матрицы, поэтому:

class Matrix
{    
public:
    vector<int> data;
    int width;

    Matrix(int w, int h) : data (w * h), width(w)
    {

    }

    int& elementAt(int x, int y)
    {
        // Offset the row with y * width, then in the row the xth element
        return data[y * width + x];
    }

    ...

Вместо vector вы можете просто выделить блок памяти, управляя им в unique_ptr ::

class Matrix
{    
public:
    unique_ptr<int[]> data;
    int width;

    Matrix(int w, int h) 
     : data (new int[w * h]), width(w) // Allocate dynamic array in unique_ptr
    {
       // Initialize data to zero
    }

    int& elementAt(int x, int y)
    {
        // Offset the row with y * width, then in the row the xth element
        return data[y * width + x];
    }

    ...

Но мне интересно, в чем суть. Я не вижу никакой очевидной разницы в эффективности. Оба автоматически освобождают память.

Функционально, у вас уже есть дополнительный шаг - обнуление данных (конечно, вы можете этого не хотеть). Кроме того, одна вещь, которую вы не имеете, это общий размер данных. vector хранит свой собственный размер, а массив - нет, поэтому вам, вероятно, придется отдельно хранить height, а также ширину.

Плюс векторы, как правило, легче программировать.

...