Все, что вы делаете, нехорошо.Сложно понять, с чего начать, поэтому позвольте мне начать с конца и представить «Правильный путь»:
typedef std::unique_ptr<Square> square_ptr;
void createSquares(std::vector<square_ptr> & v)
{
v.emplace_back(new PropertySquare1(1,"purple",120));
v.emplace_back(new PropertySquare1(2,"green",370));
// ...
}
int main()
{
std::vector<square_ptr> allSquares;
createSquares(allSquares);
for (const auto & p : allSquares)
std::cout << "ID is: " << p->getID() << std::endl;
}
Теперь, чтобы разобрать ваши проблемы:
Прежде всего,вы храните указатели локальных переменных.Эти локальные переменные умирают в конце области действия функции, и указатели становятся висящими.Разыменование - это программная ошибка.
Во-вторых, чтобы исправить это, вы должны создать динамические объекты: squareArray[1] = new PropertySquare1(1,"purple",120);
Однако это тоже проблематично.Кто-то должен будет очистить эти объекты!Вы можете перебрать массив и вызвать delete
для каждого элемента.
В-третьих, 22
- это «магическое число» (потому что оно не является ни 0
, ни 1
).Это не должно быть жестко закодировано.Если число действительно является константой времени компиляции, назовите ее где-нибудь.
В-четвертых, в любом случае, не используйте необработанные массивы.Либо используйте std::array
, если размер известен во время компиляции, либо std::vector
, если размер определяется во время выполнения.
Пятый, складывая все вместе, динамический контейнер интеллектуальных указателей позаботитсяиз всех ваших забот.Это тот, который представлен в моем коде.Альтернатива, статический массив интеллектуальных указателей, вообще не будет использовать функцию инициализации, а скорее будет инициализирована прямо на месте:
const std::size_t nfuncs = 22;
std::array<square_ptr, nfuncs> allSquares {
new PropertySquare1(1,"purple",120),
new PropertySquare1(2,"green",370),
// ...
};