Многомерный массив как член класса для размещения в куче - PullRequest
0 голосов
/ 05 июня 2019

Я программирую симуляцию для своей дипломной работы бакалавра, и я не эксперт в C ++, и после того, как я уже довольно долго искал, не находя удобного ответа или вопроса, я прибегаю к вам, ребята.

Моя проблема заключается в следующем. У меня есть некоторый класс, который имеет пару полей-членов num_a и num_b помимо других, которые могут храниться в стеке. Теперь оба эти значения примерно 1000-2000. Теперь мне нужен еще один член класса для SampleClass, а именно 2-мерный логический массив размером num_a * num_b. Из-за его размера, он должен быть распределен в куче. Он должен быть непрерывным в памяти, поэтому сохранение указателя на указатели на массивы не работает для меня.

SampleClass : Object {
   public:
         uint16_t num_a;
         uint16_t num_b;
         ??? // some data structure for my 2d array

         // simple constructor
         SampleClass(num_a, num_b);

}

Я объявляю свои классы в заголовочном файле .h и реализую функции и конструктор в исходном файле .cc.

Как видите, значения как num_a, так и num_b не определены заранее и, следовательно, не const. У меня вопрос: как (простым способом) объявить эту вещь в заголовочном файле и как я инициализирую ее в конструкторе исходного файла?

Я нашел следующее, что использует вектор:

// header file
std::vector<std::vector<bool>> *coverage_matrix;

// source file
coverage_matrix = new std::vector<std::vector<bool>>();
coverage_matrix->push_back(something); // do something with it

Работает ли этот последний подход и, что более важно, настолько ли он эффективен, как решение, не основанное на std::vector?

Спасибо за ваши ответы.

1 Ответ

3 голосов
/ 05 июня 2019

2-мерный ... массив ... размера num_a * num_b ... Из-за своего размера его необходимо распределить в куче.Он должен быть непрерывным в памяти

std::vector<std::vector<bool>>

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

 new std::vector<std::vector<bool>>()

Вряд ли когда-либо возникает необходимость динамически выделять такой вектор.Лучше избегать из соображений правильности и производительности.


Единственное решение для выделения непрерывного массива с динамическим размером - это выделение одномерного массива, где строки расположены ровно одна за другой.другой.Например:

std::vector<bool> matrix(num_a * num_b);

Вы можете получить доступ к элементу [a] [b] по индексу a + num_a * b.


Обратите внимание, что std::vector<bool> очень особенный и отличаетсяиз других векторов.Он не содержит bool объектов, а биты упакованы и доступны через маскирование и сдвиг 1 .Это делает структуру данных очень удобной для кэширования, но операции более сложными.Хорошо это или плохо для производительности, зависит от того, что вы делаете с ней, а также от архитектуры процессора.

Более важно, чем соображение производительности, это означает, что некоторые гарантии, на которые вы можете положиться с другими массивами, не 'т применяется к std::vector<bool>.Например, вы не можете взять адрес элемента, а также не можете изменять различные элементы в разных потоках без синхронизации.А что касается вашего конкретного случая, поскольку нет гарантии для объектов bool, то, безусловно, не гарантируется, что в векторе будут смежные объекты bool.

Так что, если вам нужен обычный массив bool, вам нужнообойти специализацию при использовании вектора.Например:

enum boolean : bool {no, yes};
std::vector<boolean> matrix;

1 Технически, нет гарантии какого-либо конкретного представления.Это определенная реализация.

...