С++ Array Member of Constant Length (Инициализация)
У меня есть класс, содержащий массив. Я хочу, чтобы этот массив был установлен на длину константы:
// Entities.h
class Entities
{
private:
const int maxLimit;
int objects[maxLimit];
int currentUsage;
public:
Entities();
bool addObject(int identifier);
void showStructure();
};
Основная проблема, с которой я столкнулся, связана с конструктором. Я подумал:
// Entities.cpp
Entities::Entities() : maxLimit(50)
{
currentUsage = 0;
cout << "Entities constructed with max of 50" << endl;
}
было бы достаточно... но не так. Я не знаю, могу ли я использовать список инициализаторов для инициализации массива.
Как инициализировать массив objects
с помощью maxLimit
const? Я относительно новичок в классах на С++, но у меня есть опыт работы с Java. Я в основном тестирую этот феномен "константы".
Ответы
Ответ 1
Массив должен иметь постоянную длину. Я имею в виду длину, которая одинакова для всех объектов этого класса. Это связано с тем, что компилятор должен знать размер каждого объекта, и он должен быть одинаковым для всех объектов этого конкретного класса. Итак, следующее:
class Entities
{
private:
static const int maxLimit = 50;
int objects[maxLimit];
int currentUsage;
public:
Entities();
bool addObject(int identifier);
void showStructure();
};
И в файле cpp:
const int Entities::maxLimit;
Я предпочитаю использовать перечисление для этого, потому что мне не нужно будет определять статику в файле cpp, а затем:
class Entities
{
private:
enum { maxLimit = 50 };
int objects[maxLimit];
int currentUsage;
public:
Entities();
bool addObject(int identifier);
void showStructure();
};
Если вы хотите иметь размер объекта для каждого объекта, вы можете использовать динамический массив. vector
является таким:
class Entities
{
private:
const int maxLimit;
std::vector<int> objects;
int currentUsage;
public:
Entities();
bool addObject(int identifier);
void showStructure();
};
// Entities.cpp
Entities::Entities(int limit)
: maxLimit(limit), objects(limit), currentUsage(0)
{
cout << "Entities constructed with max of 50" << endl;
}
Лучше всего сделать как можно больше инициализации в списке инициализации.
Ответ 2
Вы можете использовать аргумент шаблона, если вам нужно установить размер массива во время компиляции:
template<size_t maxLimit>
class Entities
{
int objects[maxLimit];
public:
Entities() {}
...
};
Entities<1000> inst;
Ответ 3
для динамического выделения памяти вам может понадобиться использовать "новое" ключевое слово, например
Объекты будут определены следующим образом:
int * objects;
внутри конструктора, который вы бы сделали:
objects = new int [maxLimit];
изменить:
забыл упомянуть, вам нужно будет освободить массив, когда вы закончите, возможно, в деструкторе класса.
delete[] objects;
Ответ 4
const int
должны быть инициализированы при объявлении. Если вы не знаете значения, которое оно должно быть во время объявления, вам придется принять другую стратегию.
Вам нужно будет создать массив в конструкторе, сохраняя указатель снаружи. Это то, что вы хотите сделать?
В вашем классе:
private:
int maxLimit;
int* objects;
И снаружи:
Entities::Entities() : maxLimit(50)
{
currentUsage = 0;
cout << "Entities constructed with max of 50" << endl;
objects = new int[maxLimit];
}
Entities::~Entities()
{
delete [] objects;
}
Ответ 5
Если все объекты имеют одинаковую длину, длина может быть статической. Это делает его постоянным интегральным выражением, разрешенным как связанный массив:
class Entities
{
private:
static const int maxLimit = 50;
int objects[maxLimit];
int currentUsage;
//...
};
Помните, что sizeof (Entities) является допустимым выражением. Каждый объект Entities имеет тот же размер.
Ответ 6
Используйте std::vector, и вы получите ожидаемое поведение. Не нужно беспокоиться о указателях, копиях и т.д.
#include <vector>
class Entities
{
private:
const int limit;
std::vector<int> objects;
public:
Entities(int a_limit)
: limit(a_limit), objects(a_limit)
{ }
void addObject(int identifier)
{
if (objects.size() == limit)
throw whatever;
objects.push_back(identifier);
}
};