Правильный файл класса? - PullRequest
0 голосов
/ 04 марта 2019

enter image description here

Добрый вечер всем, мне просто интересно, есть ли у меня правильный файл класса для этого.Я действительно колючий, когда дело доходит до указателей и классов.Я исследовал указатели, но думаю, что запутываю себя.Я знаю, что делают указатели и смысл их использования, но я запутался, фактически используя их и передавая их.

Дальнейшее описание класса:

"Этот класс содержит информацию дляКомната в лабиринте. Каждый объект Комната состоит из четырех указателей проходов (по одному для каждого направления), имени и списка элементов в этой комнате. В дополнение к параметризованному конструктору этот класс должен иметь следующие методы:

GetName () Возвращает имя комнаты.

GetNorthPassage (), GetEastPassage (), GetSouthPassage (), GetWestPassage () Каждый из этих методов возвращает указатель на соответствующий проход. Это позволяетдля вызовов, таких как «someRoom-> GetNorthPassage () -> Open ()»

AddItem (std :: string item) Добавляет элемент в вектор элементов объекта Room.

AcquireNextItem() Когда игрок входит в комнату, он должен получить все предметы в этой комнате.

AcquireNextItem возвращает по одному предмету за раз и удаляет его изom the Room. "

Моя реализация класса Room:

// // Created by Johnny Mitchell on 3/3/2019. //

#include "Room.hpp"

Room::Room() {}

Room::Room(std::string name, Passage *northPassage, Passage
*eastPassage, Passage *southPassage, Passage *westPassage) {
    this -> name = name;
     }

std::string Room::GetName() {
    return room; }

Passage* Room::GetNorthPassage() {
    return northPassage; }

Passage* Room::GetEastPassage() {
    return eastPassage; }

Passage* Room::GetSouthPassage() {
    return southPassage; }

Passage* Room::GetWestPassage() {
    return westPassage; }

void Room::AddItem(std::string item) {
    items.push_back(item); }

std::string Room::AcquireNextItem() {
    while (items.empty() == false)
        return items.pop_back(); }

" Room.hpp "

//
// Created by Johnny Mitchell on 3/3/2019.
//

#ifndef MAZE_ROOM_HPP
#define MAZE_ROOM_HPP


#include <string>
#include <vector>
#include "Passage.hpp"

class Room {
private:
    std::string name;
    std::vector<string> items;

    Passage* northPassage;
    Passage* eastPassage;
    Passage* westPassage;
    Passage* southPassage;

public:
    Room();
    Room(std::string name, Passage*, Passage*, Passage*, Passage*);

    std::string GetName();

    Passage* GetNorthPassage();
    Passage* GetWestPassage();
    Passage* GetSouthPassage();
    Passage* GetEastPassage();

    void AddItem(std::string item);
    std::string AcquireNextItem();

};


#endif //MAZE_ROOM_HPP

Ответы [ 2 ]

0 голосов
/ 04 марта 2019

Итак, ваш вопрос касается указателей и классов?

В C ++, когда вы определяете что-то вроде int или class любого типа, вы просто называете какой-то адрес памяти и указываете, сколько байтов после этого адреса вы хотите зарезервировать.

Например, когда вы определяете int, вы указываете компьютеру резервировать 4 байта памяти, начиная, например, с адреса 1234567.

Указатель указывает на место в памяти.

Чтобы уточнить это, память компьютера организована в байтах, каждый байт составляет 8 бит.Каждый байт имеет идентификатор или номер, представляющий его адрес.В компьютерах могут быть миллиарды различных байтовых адресов, поскольку компьютеры могут иметь гигабайты памяти.

Указатель указывает на место в памяти или адрес байта.Поскольку для определенных вещей компьютер хранит стандартизированный объем памяти, этот указатель может представлять нечто большее, чем байт.Например, целое число составляет 4 байта.

Думайте об указателях как о числе, которое при обращении компьютера по этому адресу памяти возвращает определенное количество байтов, которое вам нужно.

С помощью указателей вы можете читать некоторые байты, начиная с адреса памяти, на который указывает указатель, а также изменять значение этих байтов.

Теперь, если вы думаете о указателе на класс, он действительно такой же, как int.Вы можете использовать адрес памяти, который вы назвали своим экземпляром класса, например:

class A{
};

A myclass; // This means myclass is allocated in memory starting at some number  eg 12345

Или вы можете создать указатель на этот класс, например:

class A{
};

A * myclass = new A(); //my class now has some memory value eg 12345 and there is a class object of type A at that address , exactly the same as the first example just different way of allocating memory.

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

0 голосов
/ 04 марта 2019

В

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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...