2016-02-28 7 views
2

Мне нужен 2-й массив с фиксированной шириной и высотой, который может изменять только отдельные значения, хранящиеся в нем. Он объявляется в заголовке и позже инициализируется в исходном файле.Как инициализировать int * const * const?

Что я нашел, заставил меня попробовать следующие фрагменты; к сожалению, вопросы касались либо 1d, либо неконстантных массивов и не соответствовали моей ситуации.

int *const *const a = new int[10][10]; 
int *const *const b = new int[10][10](); 
int *const *const c = new int*[10]; 
for (int i = 0; i < 10; ++i) { 
    c[i] = new int[10]; 
} 

Моя надежда была в последнем примере, но как я могу использовать «внутренние» массивы c если они не инициализированы, и я не смог инициализировать их, так как они Const?

Мне не нужен другой тип для этого массива? Я думал о int d[][], но он не имеет постоянной ширины и высоты.
Мне кажется, что парадокс (если он существует в мире C++), я что-то упускаю?

+2

2D-массив с фиксированной шириной и высотой будет 'Int А [10] [10]'. Вы создаете массивы указателей. – molbdnilo

+0

Это заставляет меня знать размер в заголовке, о котором я еще не знаю. Вот почему я хотел объявить int * const * const. –

+0

Или это плохая идея иметь такие массивы?Я мог бы удалить его из заголовка и получить геттер, но разве это не избыток? Даже в этом случае невозможно инициализировать такие массивы? Тогда зачем они существуют? –

ответ

2

Я думал о int d[][], но он не имеет постоянной ширины и высоты.

int d[][] не имеет смысла (и будет отклонен компилятором). Что касается многомерных массивов, то для обозначения неполного типа можно исключить только размер первого измерения. Размеры других размеров являются частью этого типа. Вы не можете их опустить, как вы не можете опустить int.

Другими словами, если у вас есть что-то вроде int d[5][10], вы можете думать об этом как о одномерном массиве типа элемента int[10]. Вообще, подумайте о многомерных массивах как частный случай одномерных массивов. Это упростит понимание.


Лучшее решение для вашей проблемы в C++ является создание класса с частными std::array<T, Width * Height> data; и int width переменных-членов внутри, и вычислить массив смещения от отдельных х и у аргументов в функции публичного члена, например:

T& operator()(int x, int y) 
{ 
    return data[y * width + x]; 
} 

Если размеры известны только во время выполнения, то единственное, что вы должны изменить использует std::vector вместо std::array. Хранение все равно будет смежным.

Вот полный пример:

#include <vector> 
#include <iostream> 

class Matrix 
{ 
public: 
    Matrix(int width, int height, int value) : 
     width(width), 
     data(width * height, value) 
    {} 

    int& operator()(int x, int y) 
    { 
     return data[y * width + x]; 
    } 

private: 
    int width; 
    std::vector<int> data; 
}; 

int main() 
{ 
    Matrix m(5, 10, 123); 
    std::cout << m(7, 8) << "\n"; 
    m(7, 8) = 124; 
    std::cout << m(7, 8) << "\n"; 
} 
+0

Спасибо, теперь я нахожу этот подход лучше. –

1

Моя надежда была в последнем примере, но как я могу использовать «внутренние» массивы с, если они не инициализируются и я не могу для их инициализации, поскольку они являются константами?

Это не совсем соответствует истине:

int * const * const c = new int*[10] 
{ 
    new int[10], new int[10], new int[10], new int[10], new int[10], 
    new int[10], new int[10], new int[10], new int[10], new int[10] 
}; 
+0

Да, но OP добавлен в комментарий - «Это заставляет меня знать размер в заголовке, о котором я еще не знаю. Вот почему я хотел объявление int * const * const». – zoska

Смежные вопросы