Мне было интересно, можно ли объявить массив (размер в настоящее время неизвестен) как частный член класса, а затем установить размер в конструкторе класса. Например:
class Test {
int a[];
public:
Test(int size);
};
Test::Test(int size) {
a[size]; // this is wrong, but what can i do here?
}
Возможно ли это, или мне следует использовать динамические массивы? Спасибо!





Прежде всего, как правило, лучше инициализировать объекты в списке инициализации конструктора, а не в теле конструктора.
Вы можете инициализировать массив с предопределенной границей, только если вы знаете эту границу во время компиляции. В этой ситуации вам нужно будет динамически распределять пространство.
Тогда вы должны помнить, что у вас есть деструктор, который удалял бы массив при уничтожении объекта, иначе вы получите утечку памяти.
Краткий ответ: Нет (размер массива определяется только во время компиляции)
Длинный ответ:
Вы можете использовать вектор для достижения того же результата:
class Test
{
std::vector<int> a;
public:
Test(std::size_t size):
a(size)
{}
};
Ненавистники любят ненавидеть анонимно. Ненавижу ненавистников! Даю вам точку.
+1 Для хорошего практического ответа, если у кого-то есть проблемы с этим, объясните, почему (чтобы мы могли показать вам, что Мартин прав)
+1 от меня к, std :: vector <> отлично. Незначительной придиркой было бы использовать size_t вместо int для ctor.
@Andreas Magnusson: Мы заметили. Обновлено. Но если ваш векторный размер выходит за пределы подписанного int, я думаю, у вас есть другие проблемы.
Нет, это невозможно. Объявления массивов в заголовках должны иметь значение постоянного размера. В противном случае такие конструкции, как "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);
};
Необходимо добавить CopyConstructor и оператор присваивания и вызвать правильную версию od delete. Или используйте вектор.
Драт. Я обычно вызываю других людей с той же проблемой ... Скоро исправлю
Double Wrong; (Это логичная пятница
Однозначно согласен, что вектор лучше. Исходный образец не использовал STL, поэтому я решил ответить без STL. STL делает C++ намного лучше. Мне все труднее и труднее разделять двоих
Скорее всего, вам также понадобится переменная, в которой хранится размер файла.
Нет, это невозможно. Вам следует использовать динамический массив, такой как std::vector. C99 позволяет структуре иметь массив без размера только в качестве члена последний, но даже когда вы это делаете, вам все равно придется вручную выделять память самостоятельно, например с malloc().
Как указывали другие ответы, размер массива фиксируется во время компиляции. Однако с помощью шаблонов вы можете параметризовать размер во время компиляции:
template <int N> class Test {
int a[N];
public:
Test() { }
};
Test<5> test;
Test<40> biggertest;
Этот метод не позволяет вам вычислить размер во время бег (как это делает динамическое решение std::vector), но в зависимости от ваших потребностей этого может быть достаточно.
Это работает, но теперь каждая версия Test представляет собой отдельный класс. Таким образом, нет скрытой дружбы (следовательно, нет доступа для копирования и т. д.).
Не то чтобы вы все равно могли скопировать Test <2> в Test <1> - это не подошло бы. Кроме того, нет полиморфизма - Test <1> и Test <2> являются несовместимыми типами, поэтому каждая функция, которая их обрабатывает, также должна быть шаблонизирована.
не беспокойся. он все еще может шаблонизировать оператор = и cctor.
@Greg: Интересный совет. Еще одна причина, по которой Generics! = Templates. Или это Generics <Templates? ;-)
То, о чем вы говорите, невозможно. Классы всегда имеют постоянный размер. Вы можете использовать в своем классе указатель на динамически выделяемый массив или использовать std :: vector.
См. Решение Мартина (используйте std::vector) и помните, что даже если вам нужно передать буфер в C API, std::vector позволяет сделать это, передав &vec[0]:
std::vector<char> vec(10);
memset(&vec[0], 0, vec.size());
Это гарантированно сработает, но только если вектор не пустой (причуды C++, <sigh>).
Я часто использую трюк & vec [0], хотя memset () в этом случае не нужен, поскольку vec уже был бы инициализирован всеми нулями.
Я хочу, чтобы люди добавляли комментарии, отмечая ответы. По крайней мере, ты вернулся к 0