Привет, я пишу простую версию Pacman с ОО-дизайном на C ++. У меня проблема с отображением содержимого 2D-массива. Массив содержит набор символов, которые представляют стену карты / лабиринта. Вот пример кода, который я написал:
Game.h
class Game
{
private:
char map;
public:
Game();
void displayMap();
};
Game.cpp
char map[10][20] = {...};
void Game::displayMap()
{
for(int i = 0; i < 10; i++)
{
for(int j = 0; j < 20; j++)
{
cout << map[i][j] << " ";
}
cout << endl;
}
}
Компилятор выдаст ошибку при [i]
поговорка "expression must have pointer-to-object type"
,
Но если я определю размер массива в заголовочном файле и назначу его значение при определении конструктора
Game.h
class Game
{
private:
char map[10][20];
};
Game.cpp
Game::Game()
{
char map[10][20] = {...};
}
Он скомпилируется, но когда я пытаюсь отобразить содержимое массива (используя тот же код displayMap()
Я обнаружил, что он заполнен мусором. Я думаю, это потому, что это назначение не является назначением. Это на самом деле инициализация другого массива в стеке, так что массив уничтожается после завершения конструктора, и displayMap()
в это время отобразить исходный неназначенный массив.
Я могу ошибаться, поэтому не стесняйтесь поправлять меня. Мне нужна рекомендация о том, как я должен структурировать свою игру, чтобы избежать этой проблемы
Game::Game() {
char map[10][20] = {...};
}
Здесь вы повторно объявляете локальную переменную с тем же именем переменной экземпляра, следовательно, вы скрываете внешнюю. Кроме того, вы пытаетесь присвоить массиву, который был объявлен ранее, это не возможно в C ++. Вы можете просто инициализировать массив при его объявлении, а не после.
Вы можете сделать это (если у вас есть поддержка C ++ 11):
class Game {
char map[W][H] = { ... };
}
или вы можете сделать это:
class Game {
char map[W][H];
Game() {
char tmp[W][H] = { ... };
memcpy(map, tmp, sizeof(char)*W*H);
}
}
Даже лучше, вы можете использовать std::copy
. Или даже лучше просто использовать std::array
и забудь нормальные массивы.
Я прокомментировал ваш вопрос, но я думаю, что было бы хорошо, чтобы ответить на него, так что вот оно.
Второй вариант должен работать нормально.
Значения мусора являются нормальными в C / C ++.
Что вам нужно сделать, это инициализировать ваши значения внутри вашего конструктора (Game :: Game ()). Конструкторы предназначены для использования в этих случаях.
Поведение C / C ++ состоит в том, чтобы не назначать значение по умолчанию, оно просто «берет то, что находится в оперативной памяти». Другие языки инициализируют ячейки ОЗУ. Все зависит от того, какой язык программирования вы используете.
Включение этого кода в ваш конструктор (до доступа к карте [] [] для другого) должно работать:
for (int ix = 0; ix < 10; ix++)
for (int jx = 0; jx < 20; jx++)
map[ix][jx] = "x"; // x will be your default value