Когда использовать новое ключевое слово? - PullRequest
0 голосов
/ 02 июня 2019

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

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

Может кто-нибудь объяснить, почему это произошло. Кстати, я больше не создаю игру в куче, я показываю код, который у меня был ранее, когда я получал нулевую ссылку.

int main()
{
    sf::RenderWindow renderWindow(sf::VideoMode(640, 480), "Dungeon Run");

    //Asset test;
    //test.CreateAsset("GameAssets/Player.png");

    sf::Event event;
    renderWindow.setKeyRepeatEnabled(true);

    Game* game = new Game(renderWindow);
// Player initialized here.
    game->Initialize(); 
    while (renderWindow.isOpen()) 
    {
// Game->Player goes null in here.
        while (renderWindow.pollEvent(event))
        {

            if (event.type == sf::Event::EventType::Closed)
            {
                renderWindow.close();
            }
            //set window to random color to check if working
            if (event.type == sf::Event::EventType::KeyPressed) {
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) {
                }
                else if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) {
                }
                else if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) {
                }
                else if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) {
                }
                else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) {
                    renderWindow.close();
                }
            }
            else if (event.type == sf::Event::EventType::MouseButtonPressed) {
                if (sf::Mouse::isButtonPressed(sf::Mouse::Left)) {
                }
                else if (sf::Mouse::isButtonPressed(sf::Mouse::Right)) {
                }
            }

            renderWindow.clear();
            game->Draw(); // Here player was null when I tried to draw the sprite for the player.
            renderWindow.display();
        }
    }

delete game;
game = nullptr;
}

Класс игрока:

class Player
{
public:
    Player();
    Player(std::string name) 
        : name(name) 
    {
    }


    std::string name = "";
    double health = 100;
    double stamina = 100;
    int level = 1;
    Asset sprite;

    void attack();

    ~Player();
};


Класс актива:

Asset::Asset() {

}

void Asset::CreateAsset(std::string path) {
    if (!texture.loadFromFile(path)) {
        std::cout << "Failed to load texture from file: " << path << std::endl;
    }

    sprite.setTexture(texture);
}

sf::Sprite& Asset::GetSprite() {
    return sprite;
}

Asset::~Asset() {

}

Game.h и Game.cpp:

class Game {
private:
    Player player;
    sf::RenderWindow* window;
public:
    Game(sf::RenderWindow& window);

    void Initialize();
    void Upadte();
    void Draw();

    ~Game();
};


Game::Game(sf::RenderWindow& window) {
    this->window = &window;
    player = Player("Player");
}

void Game::Initialize() {
    player.sprite.CreateAsset("GameAssets/player.png");
}

void Game::Upadte() {
}

void Game::Draw() {
    window->draw(player.sprite.GetSprite()); // Drawing his sprite
}

Game::~Game() {
}

1 Ответ

3 голосов
/ 02 июня 2019

в современном c ++ вам почти никогда не нужно ключевое слово new

если вы хотите создать объект в куче, используйте unique_ptr или shared_ptr

вы создаете свой класс с

std::unique_ptr<Game> game = std::make_unique<Game>(renderWindow);

таким образом вам не понадобится delete, так как unique_ptr позаботится об этом за вас, когда он выйдет за рамки.

, поэтому просто замените строку new на приведенную выше и удалите строку с delete

для использования std::unique_ptr

может потребоваться следующее включение
#include <memory>

что касается "почему" у вас возникла проблема: ответственный код еще не опубликован, но я предполагаю, что у вас есть другое место, где игра удалена или установлена ​​на nullptr

...