Во-первых, настоятельно избегайте самостоятельного использования сырых указателей в C ++ - это почти всегда плохая идея.Если нет подходящего класса контейнера, используйте std::unique_ptr
.Таким образом, ваш код становится:
auto matrix = std::make_unique<double* []>(10);
for(int i=0;i<10;i++) {
matrix.get()[i]= std::make_unique<double []>(10);
}
Этот код все еще не то, что вы хотите.Обычно не рекомендуется создавать свою матрицу NxN, используя N вызовов new
или n конструкций вектора.Сделайте одно распределение NxN double, а затем либо оберните его в класс MyMatrix
, который поддерживает 2-параметрический оператор квадратной скобки, т. Е.
template <typename T>
class MyMatrix {
// etc. etc
double const T& operator[](size_type i, size_type j) const { return data_[i*n + j]; }
double T& operator[](size_type i, size_type j) { return data_[i*n + j]; }
}
, либо (не рекомендуется) иметь точку указателяв область однократного выделения:
size_t n = 10;
auto matrix_data = std::make_unique<double []>(n * n);
auto matrix = std::make_unique<double* []>(n);
for(int i=0;i<10;i++) {
matrix.get()[i] = matrix_data.get() + i * n;
}
в каждом из этих случаев вы можете позже использовать std::fill
, чтобы установить все значения матрицы на NaN вне цикла.
Последний примерВышеприведенное также может быть преобразовано в использование векторов (что, вероятно, является лучшей идеей, чем просто необработанные указатели, если вы не используете свой собственный класс):
size_t n = 10;
auto matrix_data = std::vector<double>(n * n);
auto matrix = std::vector<double*>(n);
for(auto& row : matrix) {
auto row_index = std::dist(row, matrix.begin());
row = &matrix_data[row_index * n];
}
Опять же, я не рекомендую это - этопо-прежнему C-подобный способ включения синтаксиса my_matrix[i][j]
, в то время как использование класса-оболочки позволяет получить my_matrix[i,j]
без необходимости в дополнительном хранилище, с инициализацией в NaN или другом значении (в конструкторе) и без использования двух указателей каждый раз, когда выполучить доступ к нему.