мошенническая ошибка инициализации игры

Я делаю простую карту для простой мошеннической игры.
Поэтому мне нужно инициализировать карту с объектами, созданными для каждой ячейки массива, получая данные из символьного массива [i] [j].
Предполагается, что такие классы CWall, CDoor определены в других файлах, таких как CWall.cpp, CWall.h, Underneath — код для инициализации в map.cpp.

Но правильно ли это кодировать?
Я думаю, что это вызывает проблему выделения памяти.

CObject CMap::insertObject(char character){
if (character = '*') {
CWall cwall;
return cwall;
}

if (character = 'D') {
CDoor cdoor;
return cdoor;
}

if (character = 'F') {
CFood cfood;
return cfood;
}

if (character = 'K') {
CKey ckey;
return ckey;
}

if (character = 'M') {
CMMonster cmmonster;
return cmmonster;
}

if (character = 'm') {
CMonster cmonster;
return cmonster;
}

if (character = '@') {
CPlayer cplayer;
return cplayer;
}

if (character = 'P') {
CPrincess cprincess;
return cprincess;
}

if (character = '&') {
CRock crock;
return crock;
}

if (character = 'S') {
CShield cshield
return cshield;
}

else {
CShield cshield;
return cshield;
}
}

void CMap::initialize(char arr[][COLS]){
for (int i = 0; i <= 11; i++){
for (int j = 0; j <= 38; j++){
char character = arr[i][j];
insertObject(character);
}
}
}

0

Решение

Ну, во-первых, вы на самом деле ничего не инициализируете. CWall* cwall = new CWall; было бы правильным способом динамического размещения и инициализации нового объекта CWall (при условии, конечно, что CWall имеет конструктор по умолчанию) или любого объекта в этом отношении.

То, что вы также должны иметь в виду, это то, что для всего, что вы выделяете newВы должны иметь дело с delete потом. Таким образом, вам нужно будет немного подумать о том, как вы сохраняете эти выделенные объекты, чтобы вы могли убедиться, что ваша деструктор или функция очистки удалит их все, когда вы закончите. Одним из шаблонов проектирования, который следует рассмотреть, будет Объектный пул, хотя есть несколько десятков хороших способов сделать это. Это работа, которую вам придется делать самостоятельно, так как только вы знаете достаточно о своем проекте, чтобы выбрать правильный шаблон дизайна. (Та книга, на которую я ссылаюсь, — отличный ресурс.)

РЕДАКТИРОВАТЬ: Согласно вашему комментарию, есть еще одна проблема, это то, что вы возвращаете различные типы объектов. Это простая проблема наследование — до тех пор, пока все эти объекты наследуются от абстрактного базового класса CObject (или что-то подобное), вы можете просто перечислить тип возвращаемого значения как CObject*, Затем, пока вы возвращаете объект (или указатель на объект), который наследуется от CObject, ты золотой.

РЕДАКТИРОВАТЬ 2: всякий раз, когда вы используете newвы на самом деле получаете указатель на динамически размещенный объект. Это создает некоторые собственные проблемы, в том числе new может вернуть нулевой указатель в случае неудачного размещения. Не забудьте проверить это! Умный указатель может предотвратить многие из этих проблем, но использование умных указателей зависит от выбора шаблона проектирования.

0

Другие решения

Это не правильный способ сделать это. Вы подвержены нарезка объектов, так как я думаю, что ваш CObject является объектом, а не указателем на некоторый объект. Вам нужно либо вернуть указатель типа CObject* в вашей функции, то для каждого случая вернуть new CMonster или же new CPlayer и т.д. Еще лучше, используйте вместо этого умный указатель.

То, что вы пытаетесь реализовать, называется шаблон фабричного метода, см. например Как правильно реализовать шаблон фабричного метода в C ++ Больше подробностей.

3

В то время как другие правильно указали, как кодировать идею, которую вы хотите закодировать, я остановлюсь на другом. А именно, неправильное использование полиморфизма здесь. Наследование всего от бессмысленного Object пахнет как Java, и не приветствуется в C ++. Между Принцессой и Монстром просто нет ничего общего (один поцелован, другой убит, и делать то, что ему по вкусу), поэтому, когда оба наследуются от Объекта, крайне сложно запрограммировать правильную игру. механик. Вам также нужно будет сохранить фактический тип объекта (скажем, перечисление), а затем привести к этому типу — потому что только один из них будет иметь метод kiss() на них!

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

Вместо этого используйте строго типизированный подход. Всегда знайте, какой тип перед вами!

2

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

Лучший подход был бы:

CObject* CMap::insertObject(char character){
if (character = '*') {
return new CWall();
}
...

Это будет использовать полиморфизм, чтобы скрыть фактический класс (такой как CWall) за универсальным интерфейсом (CObject). Как вы написали, каждый «новый» объект, такой как cdoor, будет фактически передан в конструктор копирования для CObject, Ничего из этого на самом деле не достигло ничего значимого.

Конечно, вам нужно соединить эти творения с соответствующими разрушениями в будущем.

1
По вопросам рекламы [email protected]