Объект класса в качестве поля другого класса. Объявление и определение. С++

323
07 марта 2018, 07:57

Помогите разобраться. В классе GameState есть приватное поле типа Level (level1). У класса Level нет конструктора по умолчанию. Не пойму как мне объявить объект класса Level в заголовочном файле, не указав параметры в конструктор (спрайт, который в параметрах потом берется из картинки, позже в файле .cpp). Ругается, что я объявил Level level1, а не с конструктором с тремя параметрами, но мне то нужно позже проинициализировать, когда текстуры подъедут итп. Эта писанина на SFML C++. Жирным выделил, то как я хочу и где на что. ругается

    class GameState : public State
    {
    public:
        GameState(GameDataRef data);
        void Init();
        void HandleInput();
        void Update(float dt);
        void Draw(float dt);
    private:
        GameDataRef _data;  
        sf::Sprite _tilesetLandscapes;
        Level level1;//здесь объявляю с пустым конструктором, которого нету 
        int gameState;
    };

class Level
{
private:
public:
    Level(int cellsInWidth, int cellsInHeight, sf::Sprite &tileSetForLevel);    
    ~Level();
};

    GameState::GameState(GameDataRef data) : _data(data)
    {
    }
    void GameState::Init()
    {   
        _data->assets.LoadTexture("Tileset_Landscapes", "Assets\\Tileset_lanscapes.png");
        _tilesetLandscapes.setTexture(this->_data->assets.GetTexture("Tileset_Landscapes"));
    level1(4, 3, _tilesetLandscapes); //Здесь хочу инициализировать level1
        level1.draw(_data->window);
    }

UPD В общем сделал все эти текстуры отдельно, подсмотрел в одном видео. Там через умные указатели, рано или поздно надо было все равно нормальный ресурс-менеджер делать без кучи вызовов и дубликатов в памяти ресурсов. Теперь то, что я не мог нормально инициализировать выглядит вот так:

GameState::GameState(GameDataRef data) : level1(6, 6), _data(data), _test(sf::Vector2f(120, 50), DUNGEON_WALL)

И пока не было этих sfml-ных проблем с белым заполнением спрайта заместо текстуры.

Answer 1

Вот тут

GameState::GameState(GameDataRef data) : _data(data)

вам нужно вызвать еще и конструктор level с передачей ему соответствующих аргументов:

GameState::GameState(GameDataRef data) : _data(data), level1(...,...,...)

Зачем у вас вообще отдельная функция Init()? Логично ведь инициализировать все в конструкторе :)

Answer 2

Можно использовать boost::optional, а для счастивчиков std::optional из C++17.

class GameState 
{
...
private:
    ....
    std::optional<Level> level;
    ....
}
GameState::GameState(GameDataRef data) : _data(data)
{
}
void GameState::Init()
{   
    _data->assets.LoadTexture("Tileset_Landscapes", "Assets\\Tileset_lanscapes.png");
    _tilesetLandscapes.setTexture(this->_data->assets.GetTexture("Tileset_Landscapes"));
    level1.emplace(4, 3, _tilesetLandscapes);
    level1->draw(_data->window);
}

Память под Level будет выделена вместе с классом, т.е. никакой дополнительной динамической алокации не бедет. Но если обратиться к непроинициализированному level, то будет AV

READ ALSO
Qt, C++ | Обращение к объектам формы

Qt, C++ | Обращение к объектам формы

Вопрос:как из функции-обработчика обратиться к объектам на форме Ui

254
while(cin) как выйти из данного цикла

while(cin) как выйти из данного цикла

Разбираю калькулятор из книги Страуструпа, лексемы вроде как считывает правильно, но не могу понять как выйти из циклаЕсли ввожу ctrl + z выдаёт...

295
Создать новый стек со значениями из другого стека

Создать новый стек со значениями из другого стека

Создать стек с числами в диапазоне от –50 до +50После создания стека выполнить индивидуальное задание

364
Перевод из десятичной СС в двоичную

Перевод из десятичной СС в двоичную

Добрый день, есть такой код, переводящий число из 10-й системы в 2-ю

271