Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Template classes circular dependency issue (c++)

I wanted to implement an observer pattern for an event system, but the compiler gives me a bunch of errors and I’m currently not able to fix them. I have two templated class in two different headers, a listener and a event dispatcher and both needs to store pointers to the other class.

In Dispatcher.h

//Dispatcher.h
#pragma once
#include "Listener.h"

template <typename T>
    class Dispatcher {
    private:
        std::vector<Listener<T>*> m_listeners;

    public:
        Dispatcher() {}
        ~Dispatcher() {
            for (Listener<T>* l : m_listeners) {
                delete l;
            }
        }

        void Attach(Listener<T>* listener) {
            m_listeners.push_back(listener);
        }

        void Detach(Listener<T>* listener) {
            std::vector<Listener<T>*>::iterator it = std::find(m_listeners.begin(), m_listeners.end(), listener);
            if (it != m_listeners.end()) {
                m_listeners.erase(it);
            }
        }

        void Notify(T& event) {
            for (Listener<T>* l : m_listeners) {
                l->OnEvent(event);
            }
        }

    };

In Listener.h

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

//Listener.h
#pragma once
#include "Dispatcher.h"

template <typename T>
class Listener {
private:
    Dispatcher<T>* m_dispatcher;
protected:
    Listener(Dispatcher<T>* dispatcher) : m_dispatcher(dispatcher) {
        m_dispatcher->Attach(this);
    }

public:
    virtual ~Listener() {
        m_dispatcher->Detach(this);
    }

    virtual void OnEvent(T& event) = 0;
};

The compiler seems to complain about not being able to find declaration for the listener. What’s wrong with this? Could someone explain? Thanks.

P.S. Obviously there’s a cpp file which includes both headers.

>Solution :

You can solve this problem of circular dependency by removing the #include "Listener.h" from Dispatcher.h and instead adding a forward declaration for class template Listener<> as shown below:

Dispatcher.h

#pragma once

#include <vector>
//no need to include Listener.h


//forward declaration 
template<typename T> class Listener;

template <typename T>
    class Dispatcher {
    private:
        std::vector<Listener<T>*> m_listeners;

    public:
        Dispatcher() {}
        ~Dispatcher() {
            for (Listener<T>* l : m_listeners) {
                delete l;
            }
        }

        void Attach(Listener<T>* listener) {
            m_listeners.push_back(listener);
        }

        void Detach(Listener<T>* listener) {
            std::vector<Listener<T>*>::iterator it = std::find(m_listeners.begin(), m_listeners.end(), listener);
            if (it != m_listeners.end()) {
                m_listeners.erase(it);
            }
        }

        void Notify(T& event) {
            for (Listener<T>* l : m_listeners) {
                l->OnEvent(event);
            }
        }

    };

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading