С++ ошибка: повторное определение

При компиляции возникает ошибка повторного определения

in file included from /home/navnica/Рабочий стол/snake/include/Ui/Button.hpp:1,
                 from /home/navnica/Рабочий стол/snake/include/Snake/StartWindow.hpp:4,
                 from /home/navnica/Рабочий стол/snake/src/Snake/StartWindow.cpp:1:
/home/navnica/Рабочий стол/snake/include/Snake/GameObject.hpp:4:11: ошибка: повторное определение «class snake::GameObject»
    4 |     class GameObject : public sf::RectangleShape{
      |           ^~~~~~~~~~
In file included from /home/navnica/Рабочий стол/snake/include/Snake/Scene.hpp:2,
                 from /home/navnica/Рабочий стол/snake/include/Snake/StartWindow.hpp:2:
/home/navnica/Рабочий стол/snake/include/Snake/GameObject.hpp:4:11: замечание: предыдущее определение «class snake::GameObject»
    4 |     class GameObject : public sf::RectangleShape{
      |           ^~~~~~~~~~

GameObject.hpp

 #include "SFML/Graphics.hpp"
    
    namespace snake{
        class GameObject : public sf::RectangleShape{
        public:
            std::string name;
    
            void logic();
    
        private:
            void setup();
        };
    }

Button.hpp

#include "Snake/GameObject.hpp"
#include "SFML/Graphics.hpp"
#include "iostream"

namespace Ui{
    class Button : public snake::GameObject{
    public:
        Button();
        void logic();

    private:
        void setup();
    };
}

StartWindow.hpp

#include "SFML/Graphics.hpp"
#include "Snake/Scene.hpp"
#include "iostream"
#include "Ui/Button.hpp"

namespace snake{

    class StartWindow{
    public:
        StartWindow();

    private:
        sf::RenderWindow *window;
        std::vector<Scene> scenes;

        void startGameLoop();
        void settingWindow();
        void drawScenes();
        void gameLogic();
    };

}

Если в StartWindow.hpp не импортировать Button.hpp, то всё работает нормально, но проблемы это не решает


Ответы (1 шт):

Автор решения: Mikhailo

Повторное определение из-за того, что из-за повторных включений один и тот же заголовочный файл включается дважды.

Чтобы этого избежать, испоользуется или защита с макросом

// В начале заголовочного файла
#ifndef __КАКОЕ_ТО_УНИКАЛЬНОЕ_ИМЯ__
#define __КАКОЕ_ТО_УНИКАЛЬНОЕ_ИМЯ__

.....

// в конце заголовочного файла
#endif

Так при втором включении __КАКОЕ_ТО_УНИКАЛЬНОЕ_ИМЯ__ уже будет определено и файл не будет включен.

Или использовать

#pragma once

в начале файла (не уверен, что эту строку поймут все компиляторы, но многие точно. Если не поймут - остаеттся метод с макросом).

→ Ссылка