Чтобы повторить вышеприведенные ответы, я бы, безусловно, указал вам на std::vector
, так как это наилучшее возможное решение.Управление своими собственными динамическими массивами в C++
- почти - никогда не является хорошей идеей, а почти никогда не требуется.
Однако, чтобы ответить на прямой вопрос - вВ этой ситуации вы можете создать конструктор по умолчанию и некоторые мутаторы, чтобы получить желаемый эффект:
class BattlePoint {
public:
// default constructor, default initialize to 0,0
BattlePoint() x(0), y(0) {};
BattlePoint(int x, int y) : x(x), y(y) { };
bool operator==(const BattlePoint &right);
virtual ~BattlePoint();
// mutator functions allow you to modify the classes member values
void set_x(int x_) {x = x_;}
void set_y(int y_) {y = y_;}
private:
int x, y;
};
Затем вы можете инициализировать это так, как вы привыкли в C
:
BattlePoint* points = new BattlePoint[100];
for(int x = 0; x < 100; ++x)
{
points->set_x(x);
points->set_y(x * 2);
}
Если вам надоело сделать публично изменяемый класс BattlePoint
, вы можете оставить мутаторы закрытыми и ввести функцию Friend специально для инициализации значений.Это немного более сложная концепция, поэтому я пока воздержусь от дальнейших пояснений по этому поводу, если только в этом нет необходимости.
Так как вы спросили:)
Создайте свой класс BattlePoint
снова сконструктор по умолчанию и мутаторы, однако на этот раз оставьте мутаторы закрытыми и объявите функцию-друг для их использования:
class BattlePoint {
public:
// default constructor, default initialize to 0,0
BattlePoint() x(0), y(0) {};
BattlePoint(int x, int y) : x(x), y(y) { };
bool operator==(const BattlePoint &right);
virtual ~BattlePoint();
private:
// mutator functions allow you to modify the classes member values
void set_x(int x_) {x = x_;}
void set_y(int y_) {y = y_;}
int x, y;
friend void do_initialize_x_y(BattlePoint*, int, int);
};
Создайте файл заголовка, который будет содержать локальную функцию для создания массива BattlePoint
объекты.Эта функция будет доступна любому, кто включает заголовок, но при правильном названии «все» должны знать, что его не следует использовать.
// BattlePoint_Initialize.h
BattlePoint* create_battle_point_array(size_t count, int* x, int* y);
Эта функция определяется в файле реализации вместе с нашей функцией Friend.что мы будем «прятаться» от внешнего мира:
// BattlePoint_Initialize.cpp
#include <BattlePoint_Initialize.h>
namespace
{
// by putting this function in an anonymous namespace it is only available
// to this compilation unit. This function can only be called from within
// this particular file.
//
// technically, the symbols are still exported, but they are mangled badly
// so someone could call this, but they would have to really try to do it
// not something that could be done "by accident"
void do_initialize_x_y(BattlePoint* bp, int x, int y)
{
bp->set_x(x);
bp->set_y(y);
}
}
// caution, relies on the assumption that count indicates the number of
// BattlePoint objects to be created, as well as the number of valid entries
// in the x and y arrays
BattlePoint* create_battle_point_array(size_t count, int* x, int* y)
{
BattlePoint* bp_array = new BattlePoint[count];
for(size_t curr = 0; curr < count; ++curr)
{
do_initialize_x_y(bp_array[curr], x[curr], y[curr]);
}
return bp_array;
}
Итак, у вас это есть.Очень запутанный способ удовлетворения ваших основных требований.
Хотя create_battlepoint_array()
теоретически можно вызывать где угодно, на самом деле он не способен изменять уже созданный объект BattlePoint
.Функция do_initialize_x_y()
, скрытая в анонимном namespace
, спрятанном за кодом инициализации, не может быть легко вызвана откуда-либо еще в вашей программе.Фактически, если объект BattlePoint
создан (и инициализирован в два этапа), он не может быть изменен далее.