В
Room::Room(std::string name, Passage *northPassage, Passage
*eastPassage, Passage *southPassage, Passage *westPassage) {
this -> name = name;
}
нет связи между параметрами northPassage
, eastPassage
, southPassage
и westPassage
и переменными-членами
Passage* northPassage;
Passage* eastPassage;
Passage* westPassage;
Passage* southPassage;
Этипараметры не устанавливают автоматически одноименные элементы.Вы должны сделать это самостоятельно.Так как члены не установлены, указатели указывают на какое-то неопределенное местоположение, и то, что это значит для вас, также не определено.Это плохо.Как только вы узнаете, как работают компьютеры, вы можете сделать некоторые предположения относительно того, что произойдет, но что бы это ни было, это не будет хорошо.Даже если кажется, что он делает то, что вам нужно, это может произойти не позже.
Параметр northPassage
и член northPassage
- это совершенно разные переменные, которые просто имеют одно и то же имя.Это не указатель, это переменная область видимости.Внутри Room::Room
, northPassage
относится к идентификатору, объявленному последним, и это является параметром.Прочтите Затенение переменных для получения дополнительной информации.
Лучший способ присвоить параметр northPassage
элементу northPassage
- использовать список инициализаторов элементов, вероятно, наименее важный для обученияКонцепция C ++ существует.
Room::Room(std::string name,
Passage *northPassage,
Passage *eastPassage,
Passage *southPassage,
Passage *westPassage):
name(name),
items(), // not strictly required here, but included for completeness.
northPassage(northPassage),
eastPassage(eastPassage),
southPassage(southPassage),
westPassage(westPassage)
{
// noting needed in here. Everything was done above
}
Предпочитаю список инициализатора члена присваиванию в теле, потому что класс должен быть полностью инициализирован, прежде чем он войдет в тело конструктора.Это не имеет значения для указателей и большинства примитивных типов данных, потому что их инициализация ничего не делает, но для класса, который требует инициализации, например std::vector<string> items
, будет вызван конструктор по умолчанию.Если вы не хотите использовать конструкцию по умолчанию, эти усилия будут потрачены впустую.Если у класса нет конструктора по умолчанию, список инициализаторов членов является ЕДИНСТВЕННЫМ способом инициализации класса.Компилятор будет кричать на вас, если вы не инициализируете член, который не может быть инициализирован по умолчанию.То же относится и к любым унаследованным классам.
Несвязанное примечание:
Одна вещь, которая действительно удивляет людей, когда в первый раз встречается, когда вы передаете указатель на переменную, переменная передается по ссылке,Указатель нет.Указатель - это автоматическая переменная, которая ограничена функцией и содержит копию переданного адреса. Если вы измените эту копию адреса, укажите ее где-нибудь еще, оригинал не изменится.Так что-то вроде:
void gimmiepointer (MyDatatype * p)
{
p = new MyDatatype();
}
просто подтекает MyDatatype
.Указатель на него вышел из области видимости и был потерян при завершении функции.
Вместо этого используйте ссылку на указатель
void gimmiepointer (MyDatatype *& p)
{
p = new MyDatatype();
}
Или передайте ничего и просто верните новый указатель
MyDatatype * gimmiepointer ()
{
return new MyDatatype();
}