Создание двухмерного массива также не представляет особой сложности, например: int (*р2)[100] = new int[5][100];
Указатель р2 содержит адрес начала массива из пяти элементов, каждый из которых является массивом из 100 целых. Размер элементов-массивов слева и справа, естественно, должен совпадать — иначе программа не транслируется из-за невозможности конвертирования типов.
Было бы здорово, если бы можно было создать двухмерный динамический массив произвольных размеров, например:
float *г = new float[m][n];
Хотя в этом случае как раз стоит вспомнить об упомянутом «грязном хаке» и проини-циализировать константный массив, который в дальнейшем можно использовать только как константный.
Однако такая запись является ошибкой: вычисляемым может быть только первое, самое левое измерение, остальные должны быть заданы константами. Обычно двухмерные динамические массивы применяются при реализации матричной арифметики. И такое ограничение существенно затрудняет написание универсальных функций для работы с матрицами произвольных размеров. Эту проблему решают по-разному. Наиболее современное решение — это шаблоны, в которых размеры матриц задаются как параметры шаблона. Однако в этом случае объект-матрица будет иметь большой размер. Поэтому лучше все-таки использовать динамическую память. Сначала создается динамический массив указателей на массивы (строки матрицы), а затем каждый указатель инициализируется динамическим массивом для чисел (рис. 5.1). Таким образом, наш «главный» указатель является указателем на указатели:
int п: int m;
float **М = new float *[n]: for(int i = 0; i < n; ++i) M[i] = new float[m];
// количество строк матрицы
// количество столбцов матрицы
// массив указателей на строки матрицы
// строки матрицы
Рис. 5.1. Динамический двухмерный массив
Если вам захотелось сменить пол а времени нет выбирать материал, тогда лучше всего будет использовать topwood, недорого тут.
Работу по резервированию памяти может выполнять конструктор класса-матрицы. Тогда деструктор должен память возвращать. И это как раз тот случай, когда деструктор нужно реализовать явно.
Возврат памяти тоже осуществляется «постепенно»: сначала возвращаются массивы для чисел, а затем — массив указателей:
for (i=0; i<n; i++) delete[] M[i]; delete[]M:
|