Инициализация переменных класса в заголовке - PullRequest
0 голосов
/ 29 марта 2020

Я новичок в C ++, пришел с Java. В качестве моего первого проекта я хочу сделать простую маленькую SFML-игру. Я разделил основной файл на заголовок и файл cpp. По сути, я инициализирую SFML RenderWindow в классе cpp. Как вы можете видеть здесь:

Main::Main() {
    this->wWidth = 1440;
    this->wHeight = 900;
    this->wTitle = "Platformer";
    this->fps = 0;
    this->window = sf::RenderWindow(VideoMode(this->wWidth, this->wHeight), this->wTitle);
    this->player = Player(100, 100, this->window);
}

Мой заголовочный файл:

class Main {
    public:
        Main();

        void tick();
        void render();
        void run();
        void spawn();
        int main();

        float fps;
    private:
        int wWidth = 1440;
        int wHeight = 900;
        std::string wTitle = "Platformer";
        sf::RenderWindow window;
        Player player;
};

Теперь это может быть моей проблемой из Java, но я хочу создать пустой экземпляр sf::RenderWindow в заголовке, а затем инициализировать его основным файлом.

Но это не сработает, sf::RenderWindow, передаваемый в Player, инициализация не будет работать, Если кто-то может сказать мне правильный способ сделать это в C ++, а не то, как вы это сделали бы в Java, это было бы хорошо, поскольку я еще не полностью понимаю терминологию C ++.

Я получаю ошибки:

Для этого:

Main::Main() {


no matching function for call to 'Player::Player()'

Для этого:

this->window = sf::RenderWindow(VideoMode(this->wWidth, this->wHeight), this->wTitle);


use of deleted function 'sf::RenderWindow& sf::RenderWindow::operator=(const sf::RenderWindow&)'

Для этого:

this->player = Player(100, 100, this->window);


use of deleted function 'Player& Player::operator=(Player&&)'

Для этого

class Player {


non-static reference member 'sf::RenderWindow& Player::window', can't use default assignment operator

Ответы [ 2 ]

2 голосов
/ 29 марта 2020

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

Main::Main() {
    ...
    this->player = Player(100, 100, this->window);
}

создает объект Player, а затем присваивает ему. Он пытается создать объект проигрывателя с помощью конструктора по умолчанию, но поскольку он не существует, вы получаете сообщение об ошибке. Вот как вы должны это сделать

Main::Main() : player(100, 100, window) {
    ...
}

Аналогично с window

Main::Main() : window(VideoMode(wWidth, wHeight), wTitle),
    player(100, 100, window) {
    ...
}

Теперь возможно, что некоторые из этих объектов действительно должны быть указателями, я бы не знал о который. Но, надеюсь, теперь вы понимаете разницу в c ++ между инициализацией и присваиванием.

2 голосов
/ 29 марта 2020

Если sf::RenderWindow не имеет конструктора по умолчанию, вы должны инициализировать его в списке инициализации Main. Это потому, что вы объявили window автоматическим c членом объекта Main, и поэтому он должен быть создан вместе со всеми другими членами Main при создании Main. Вы также должны использовать список инициализации в любом случае, так как он намного эффективнее.

Примерно так:

Main::Main() : fps(0), window(VideoMode(wWidth, wHeight), wTitle)), player(100, 100, window)  {}

(Вам не нужно инициализировать всех остальных участников, поскольку они инициализированы по умолчанию по = в шапке)

...