Объявление массива С++ в заголовке
Мне было интересно, можно ли объявить массив (размер которого неизвестен в это время), как частный член класса, а затем установить размер в конструкторе класса. Например:
class Test {
int a[];
public:
Test(int size);
};
Test::Test(int size) {
a[size]; // this is wrong, but what can i do here?
}
Возможно ли это, или я должен использовать динамические массивы? Спасибо!
Ответы
Ответ 1
Нет, это невозможно. Объявления массива в заголовках должны иметь постоянную величину. В противном случае конструкции, такие как "sizeof", не будут функционировать должным образом. Вам нужно объявить массив как тип указателя и использовать new [] в конструкторе. Пример.
class Test {
int *a;
public:
Test(int size) {
a = new int[size];
}
~Test() { delete [] a; }
private:
Test(const Test& other);
Test& operator=(const Test& other);
};
Ответ 2
Краткий ответ: Нет (размер массива определяется только во время компиляции)
Длительный ответ:
Вы можете использовать вектор для достижения того же результата:
class Test
{
std::vector<int> a;
public:
Test(std::size_t size):
a(size)
{}
};
Ответ 3
Как указывали другие ответы, размер массива фиксируется во время компиляции. Однако, используя шаблоны, вы можете параметризовать размер во время компиляции:
template <int N> class Test {
int a[N];
public:
Test() { }
};
Test<5> test;
Test<40> biggertest;
Этот метод не позволяет вам вычислять размер во время выполнения (как это делает динамическое решение std::vector
), но в зависимости от ваших потребностей этого может быть достаточно.
Ответ 4
Прежде всего, обычно лучше инициализировать вещи в списке инициализации конструктора, а не в теле конструктора.
Вы можете только инициализировать массив с предопределенной границей, если вы знаете эту привязку во время компиляции. В этой ситуации вам потребуется динамически выделять пространство.
Вы должны помнить, что у вас есть деструктор, который удалит массив, когда объект будет уничтожен, или вы получите утечку памяти.
Ответ 5
См. решение Martin (используйте std::vector
) и помните, что даже если вам нужно передать буфер в C API std::vector
, вы можете сделать это, передав &vec[0]
:
std::vector<char> vec(10);
memset(&vec[0], 0, vec.size());
Он гарантированно работает, но только если вектор не пуст (С++ quirks, <sigh> ).
Ответ 6
Нет, это невозможно. Вы должны использовать динамический массив, например std::vector
. C99 позволяет структуре иметь несертифицированный массив только как последний член, но даже когда вы это делаете, вам все равно придется вручную распределять память самостоятельно, например. с malloc()
.
Ответ 7
То, о чем вы говорите, невозможно. Классы всегда имеют постоянный размер. Вы могли бы использовать в своем классе указатель на динамически выделенный массив, или вы могли бы использовать std::vector.