Search code examples
c++sfml

How can I fix sfml c++ code compilation error?


I have created 2 .cpp files and 2 .header files

  1. main.cpp (main .cpp file)
  2. main.hpp (main header file)
  3. game.cpp
  4. game.hpp

I have used main.hpp components in game.hpp

Code:

#include <SFML/Graphics.hpp>
#include <bits/stdc++.h>
#include "Window.hpp"
using namespace std;

class Ship{
public:
    Ship();
    ~Ship();

    int ship_x=400-28;
    int ship_y=600-55;

    sf::Texture ship_texture;
    sf::Sprite ship_sprite;

    Window *window = new Window();

    void Ship_Void(){
        if(window->event.type==sf::Event::KeyPressed){
            if(window->event.key.code==sf::Keyboard::D){
                if(ship_sprite.getPosition().x<=544)
                    ship_sprite.move(sf::Vector2f(0.04, 0));
            }
            if(window->event.key.code==sf::Keyboard::A){
                if(ship_sprite.getPosition().x>=200)
                    ship_sprite.move(sf::Vector2f(-0.04, 0));
            }
            if(window->event.key.code==sf::Keyboard::W){
                if(ship_sprite.getPosition().y>=0)
                    ship_sprite.move(sf::Vector2f(0, -0.04));
            }
            if(window->event.key.code==sf::Keyboard::S){
                if(ship_sprite.getPosition().y<=545)
                    ship_sprite.move(sf::Vector2f(0, 0.04));
            }
        }
    }

    void Keys(){
        ship_texture.loadFromFile("images/spaceship.png");
        ship_sprite.setTexture(ship_texture);
        ship_sprite.setPosition(ship_x, ship_y);
    }
};

Compilation command:

g++ Window.cpp -o game -lsfml-graphics -lsfml-window -lsfml-system

Compilation error:

In file included from Ship.hpp:3,
                 from Window.cpp:2:
Window.hpp:5:7: error: redefinition of ‘class Window’
5     | class Window{
      |       ^~~~~~
In file included from Window.cpp:1:
Window.hpp:5:7: note: previous definition of ‘class Window’
5 | class Window{

Please help with fixing this error!


Solution

  • Let's say, that you want to use in main.cpp some other variables, functions, classes, or other identifiers, which you defined in game.cpp.

    The guideline is to put declarations of what you want to ever use externally in a header file.

    So if you have this content of game.cpp (there are two definitions of functions):

    #include <iostream>
    
    namespace mygame {
    
        void a() { 
           std::cout << "A";
        }
    
        int b() {
           std::cout << "B";
           return 1;
        }
    
    }
    

    and you want to use b() in your main.cpp, then you add the declaration of b in a header game.hpp:

    #ifndef GAME_HPP
    #define GAME_HPP
    
    int b();
    
    #endif
    

    then you include this header in your main.cpp by putting #include "game.hpp" on top of the main.cpp and thus you're allowed to use b() freely. So main.cpp might look like:

    #include <iostream>
    #include "game.hpp"
    
    int main()
    {
       std::cout << "MAIN";
       mygame::b();
       int x = mygame::b(); // remember that b() returns int
    }
    

    Notice that game.hpp also contains some ugly commands. They're not necessary to #include the file per se, but should be used to protect from multiple definitions. To find out more, look for Header Guards

    Also beware, as you technically can include a source file game.cpp, instead of game.hpp, but don't do that, since compiler will show you a plenty of puzzling messages. Just don't do that, until you know how preprocessor + compiler + linker work together.