c++headerinclude-guardscyclic-dependency

How to ensure #include doesn't recursively add (only adds unique files once)


I have this file main.h and this file events.h, the file events.h needs to include main.h as the singleton of my Events class requires my singleton of my Main class in order to declare Main as a friend class, so it can access Events private members/methods.

Conversely, Main also needs to include Events to call its methods, however doing #include "events.h" in main, and then #include "main.h" in events will just recursively keep pasting the header file code in each of them.

How can I avoid this so that each of them only pastes the code in once per file?

main.h

#ifndef MAIN_H
#define MAIN_H

#include "events.h"

class Main
{
public:
    Main(const Main&) = delete;
    Main(Main&&) = delete;
    Main& operator=(const Main&) = delete;
    Main& operator=(Main&&) = delete;


    static void Mainloop();




private:
    Main()
    {
        std::cout << "Main constructor called\n";
        mainloopInstanceBlocker = 'C';
    }

    static Main& Get_Instance()
    {
        static Main instance;
        return instance;
    }


    static void Init();
    static void Free();



    SDL_Window* window = nullptr;
    SDL_Renderer* renderer = nullptr;

    bool running = false;
    char mainloopInstanceBlocker = 'I';



};








#endif // MAIN_H

events.h

#ifndef EVENTS_H
#define EVENTS_H


#include <iostream>
#include <SDL2/SDL.h>
#include <string>


#include "main.h"


class Events
{
public:
    Events(const Events&) = delete;
    Events(Events&&) = delete;
    Events& operator=(const Events&) = delete;
    Events& operator=(Events&&) = delete;



    static const std::string& User_Text_Input();




private:
    Events()
    {
        std::cout << "Events constructor called\n";
    }

    static Events& Get_Instance()
    {
        static Events instance;
        return instance;
    }


    friend class Main;

    ///For event handling
    static void Event_Loop()
    {
        Get_Instance();

        if (Get_Instance().eventLoopCounter == 0)
        {

            Get_Instance().eventLoopCounter += 1;

            while (SDL_PollEvent(&Get_Instance().event))
            {
                if (Get_Instance().event.type == SDL_QUIT)
                {
                    Get_Instance().m_quit = true;
                    break;
                }
                else if (Get_Instance().event.type == SDL_TEXTINPUT)
                {
                    Get_Instance().m_User_Text_Input = Get_Instance().event.text.text;
                }


            }

        }
    }

    ///For event handling
    static void Reset_Events()
    {
        Get_Instance().eventLoopCounter = 0;

        Get_Instance().m_quit = false;
        Get_Instance().m_User_Text_Input = "";
    }

    ///For quitting, used main only
    static bool Quit_Application(){
        return Get_Instance().m_quit;
    }



    ///For Event_Loop()
    int eventLoopCounter = 0;
    SDL_Event event;




    bool m_quit = false;

    std::string m_User_Text_Input = "";



};



#endif // EVENTS_H


Solution

  • This is a linker and header file problem, you just need to add #pragma once at the top of each header files, the compiler will add the content of each header files only one time, but you must ensure that you just declare methods in your header files and write the content of those methods in other .cpp files to prevent of linking error.