@andrewjabber

Возможно ли объявить двумерный массив на unique_ptr?

Следующий фрагмент объявляет одномерный массив, управляемый unique_ptr.
class A
{
public:
    static int i;
    A(){ j = i; cout << "A " << j << endl; i++; }
    ~A() { cout << "~A " << j << endl; }
    int j;
};
int A::i = 0;

int main()
{
    {
        unique_ptr<A[]> p1(new A[6]);
    }
    return 0;
}

Можно ли объявить двумерный массив на unique_ptr по аналогии с тем, как это реализуется в vector?
#include <QDebug>
#include <iostream>
#include <memory>
using namespace std;
int main()
{
    int M = 2, N = 3;
    {
        #define VA std::vector<A>
        auto v2a = std::vector< VA >(M, VA(N));
    }
    return 0;
}

UPD
В случае комплексного двумерного массива решение лучше основывать на valarray, конструируя его по следующему принципу.
  • Вопрос задан
  • 2964 просмотра
Решения вопроса 1
@Lol4t0
Нет. Дело в том, что new не умеет создавать думерные массивы
int x  = 6; int y = 8;
ew int [x][y]; //error: the value of 'y' is not usable in a constant expression


Зато (по аналогии с вектрором, вы можете создать массив uniq_ptr-ов, ссылающийся на массив uniq_ptr-ов

typedef unique_ptr<A[]> a_arr;
typedef unique_ptr<a_arr[]> a_2d_arr;
a_2d_arr p1(new a_arr[8]);
p1[0].reset(new A[6]);
//...


Но вообще-то такой подход не очень удобен и очень неэффективен с точки зрения локальности памяти, и обычно создают одномерный массив размером mxn, который затем интерпретируют как двумерный.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
AxisPod
@AxisPod
Ну двумерных массивов в C++ нет, есть только jagged массивы.
Поэтому ручками создаете обычный массив, пихаете в unique_ptr и указываете свой делитер.
Ответ написан
Комментировать
@xseven
Возможно все и возможности программиста ограничиваются только фантазией.

Не сочтите за личный выпад.

Когда возникают подобные задачи стоит задуматься а все ли в порядке с архитектурой и можно ли написать проще?
Мне кажется такой будет тяжело поддерживать и, судя по всему, вы используете Qt и не очень понятно где там может пригодиться хранение двумерного массива указателей?

Возможно стоит рассмотреть проблему под другим углом и сделать проще?
Ответ написан
@caxa_fe
Я в подобной ситуации в конце концов сделал вектор векторов

#include <vector>

std::vector<A> row {};
std::vector<std::vector<A>> matrix {};

for ( size_t i = 0; i < rowsAmount; ++i)
{
    for( size_t j = 0; j < colsAmount; ++j)
    {
        row.push_back(objectA);
    }
    matrix.push_back(row);
    row.clear();
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы