объявление массива c ++ в заголовке - PullRequest
10 голосов
/ 26 ноября 2008

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

class Test {
int a[];
public:
Test(int size);
};

Test::Test(int size) {
a[size];   // this is wrong, but what can i do here?
}

Возможно ли это или я должен использовать динамические массивы? Спасибо!

Ответы [ 7 ]

17 голосов
/ 26 ноября 2008

Краткий ответ: Нет (размер массива определяется только во время компиляции)
Длинный ответ:

Вы можете использовать вектор для достижения того же результата:

class Test
{
    std::vector<int> a;
    public:
        Test(std::size_t size):
            a(size)
        {}
};
13 голосов
/ 26 ноября 2008

Нет, это невозможно. Объявления массивов в заголовках должны иметь значение постоянного размера. В противном случае невозможно, чтобы конструкции типа «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);
};
4 голосов
/ 26 ноября 2008

Как указывалось в других ответах, размер массива фиксируется во время компиляции. Однако с помощью шаблонов вы можете параметризовать размер во время компиляции:

template <int N> class Test {
    int a[N];
public:
    Test() { }
};

Test<5> test;
Test<40> biggertest;

Этот метод не позволяет вычислять размер в время выполнения (как это делает динамическое решение std::vector), но в зависимости от ваших потребностей этого может быть достаточно.

3 голосов
/ 26 ноября 2008

Прежде всего, обычно лучше инициализировать вещи в списке инициализации конструктора, а не в теле конструктора.

Вы можете инициализировать массив с предварительно определенной границей, если вы знаете эту границу во время компиляции. В этой ситуации вам нужно будет динамически распределять пространство.

Вы должны помнить, что у вас должен быть деструктор, который удалял бы массив, когда объект уничтожался, или вы получали утечку памяти.

2 голосов
/ 27 ноября 2008

См. Решение Мартина (используйте std::vector) и помните, что даже если вам нужно передать буфер в C API, std::vector позволяет вам сделать это, передав &vec[0]:

std::vector<char> vec(10);
memset(&vec[0], 0, vec.size());

Это гарантированно сработает, но только если вектор не пустой (причуды C ++, ).

0 голосов
/ 26 ноября 2008

То, о чем вы говорите, невозможно. Классы всегда имеют постоянный размер. Вы можете сделать так, чтобы ваш класс использовал указатель на динамически размещенный массив, или вы могли бы использовать std :: vector.

0 голосов
/ 26 ноября 2008

Нет, это невозможно. Вы должны использовать динамический массив, такой как std::vector. C99 позволяет структуре иметь неизмененный массив только как элемент last , но даже когда вы делаете это, вам все равно придется вручную выделять память, например, с malloc().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...