-
Hello everyone !
I'm currently learning SFML and C++.
I've created a little game, but the fact is I would like to delete the Player object and Obstacle object when the program is closed. I tried not to use pointers but the compiler says "obstacle.fall(10) : fall is not of type Obstacle()". And if I use pointers for dynamic allocation, it works great but when it comes to delete the objects, I have a memory error.
The delete instructions are written in Game::endGame().
Source code (just the main.cpp and Game.cpp files in order to keep things simple and clear):
main.cpp
#include <iostream>
#include <SFML/Graphics.hpp>
#include "Game.hpp"
#include "Player.hpp"
#include "Obstacle.hpp"
int main()
{
sf::RenderWindow window(sf::VideoMode(800,600), "Test", sf::Style::Fullscreen);
window.setVerticalSyncEnabled(true);
Game *game = new Game();
if(game->displayMenu(&window) != 0)
{
std::cerr << "Exiting the game..." << std::endl;
}
return 0;
}
Game.cpp
#include <iostream>
#include <SFML/Graphics.hpp>
#include "Game.hpp"
#include "Player.hpp"
#include "Obstacle.hpp"
Game::Game()
{
}
int Game::startGame(sf::RenderWindow *window)
{
window->clear(sf::Color::Black);
Player *player = new Player(360,520,40);
Obstacle *obstacle = new Obstacle();
while(window->isOpen() == true)
{
sf::Event ev;
while(window->pollEvent(ev) == true)
{
if(ev.type == sf::Event::Closed)
{
window->close();
}
if(ev.type == sf::Event::KeyPressed)
{
switch(ev.key.code)
{
case(sf::Keyboard::Escape):
window->close();
break;
case(sf::Keyboard::Left):
player->move(-20);
break;
case(sf::Keyboard::Right):
player->move(20);
break;
default:
break;
}
}
}
obstacle->fall(10);
obstacle->isInWindow();
player->isInWindow();
if(isCollision(player,obstacle) == true)
{
if(lifes > 0)
{
lifes -= 1;
}
else
{
endGame(window, player, obstacle);
}
}
obstacle->reset();
window->clear(sf::Color::Black);
player->draw(window);
obstacle->draw(window);
window->display();
}
}
}
void Game::endGame(sf::RenderWindow *window, Player *player, Obstacle *obstacle)
{
window->clear(sf::Color::Black);
while(window->isOpen() == true)
{
sf::Event ev;
while(window->pollEvent(ev) == true)
{
if(ev.type == sf::Event::Closed)
{
window->close();
delete &player;
delete &obstacle;
}
if(ev.type == sf::Event::KeyPressed)
{
switch(ev.key.code)
{
case(sf::Keyboard::Escape):
window->close();
delete &player;
delete &obstacle;
break;
case(sf::Keyboard::Return):
startGame(window);
break;
default:
break;
}
}
}
}
window->close();
}
Regards
-
I'm not entirely sure what you mean, but: you don't need to delete anything when your program execution ends, it'll be deleted automatically.
-
Thanks for your answer pw90 !
Really ? Ok then it's great ! Because I thought that in C++ everytime you create an object with a pointer you have to delete it manually.
So what you mean is that when my program exits the SFML automatically handles the deletions ?
-
Technically true-ish, but in practice, this is terrible advice.
You should really first get a good understanding of C++ before you dive into SFML. If you don't understand the concept of life-time, pointers, references (new and delete), it indicates to me that you haven't spent much time reading up on these topics.
With C++11 (man 7 years already?!) you get unique_ptr which makes manual new and delete calls obsolete.
-
Yes indeed ! I'm just very interesed in computer programing, never studied it at school but find it so cool. So that's great news, because I was learning some old tutorials (written when I was a teenager ahah) that's why it's a bit outdated.
Anyway, the point is that since the C++11 standard, we can use :
Foo *foo = new Foo("Foo",4,4);
And don't need to call :
Foo *foo = new Foo("Foo",4,4);
delete foo();
?
Regards
-
Hmm.. I wonder why obstacle.fall( 10 ) would give out an error "obstacle.fall( 10 ) is not of type Obstacle"...never got one of those...why not post Obstacle class too :D
also to answer your question
Foo *foo = new Foo( "Foo", 4, 4);
you still need to call ( I am pretty sure )
delete foo;
if you use unique_ptr ( which is the correct way since C++11. Unless you really need raw pointer )
std::unique_ptr< Foo > foo = std::make_unique( new Foo{ "Foo", 4, 4 } );
there is no need to call delete
I learnt C++ here : http://www.cplusplus.com/doc/tutorial/ although the site has bad reputation, it works for me
best way to learn C++ is through books :D
-
Thank you guys ! It works now !
The syntax I used is :
std::unique_ptr<Player> player = std::make_unique<Player>(360,520,40);
std::unique_ptr<Obstacle> obstacle = std::make_unique<Obstacle>();
And I changed the functions prototypes :
Before :
bool Game::isCollision(Player *player, Obstacle *obstacle)
After :
bool Game::isCollision(std::unique_ptr<Player> &player, std::unique_ptr<Obstacle> &obstacle)
I did try with destructors in the .hpp files to print a message when the objects are destroyed and indeed it works perfectly !