Объявление массива С++ в заголовке

Мне было интересно, можно ли объявить массив (размер которого неизвестен в это время), как частный член класса, а затем установить размер в конструкторе класса. Например:

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.