I encountered the following linker errors and I can't seem to find out why Observable<T>
doesn't get defined:
CMakeFiles/Sapling.dir/Core/Window/SdlWindow.cpp.o: In function `se::SdlWindow::SdlWindow(se::Window::State const&)':
/home/glados/ClionProjects/Sapling/Core/Window/SdlWindow.cpp:9: undefined reference to `se::Observable<se::WindowEvent>::addObserver(se::Observer<se::WindowEvent>*)'
CMakeFiles/Sapling.dir/IO/SdlInput.cpp.o: In function `se::SdlInput::processEvent(SDL_Event const&)':
/home/glados/ClionProjects/Sapling/IO/SdlInput.cpp:83: undefined reference to `se::Observable<se::WindowEvent>::notify(se::WindowEvent const&)'
collect2: error: ld returned 1 exit status
The problem seems to be about these two classes:
Observer.h
#ifndef OBSERVER_H
#define OBSERVER_H
#include "../Util/UID.h"
namespace se {
template <typename T>
class Observer {
public:
Observer();
virtual ~Observer() { }
virtual void onNotify(const T& subject) = 0;
const UID& getId() {
return m_id;
}
private:
UID m_id;
static UIDPool m_uidPool;
};
} // namespace se
#endif
Observer.cpp
#include "Observer.h"
namespace se {
template <typename T>
UIDPool Observer<T>::m_uidPool = UIDPool();
template <typename T>
Observer<T>::Observer() : m_id(&m_uidPool) { }
} // namespace se
Observable.h
#ifndef OBSERVABLE_H
#define OBSERVABLE_H
#include "Observer.h"
#include <vector>
namespace se {
template <typename T>
class Observable {
public:
void addObserver(Observer<T>* observer);
void removeObserver(Observer<T>* observer);
protected:
void notify(const T& topic);
private:
std::vector<Observer<T>*> m_observers;
};
} // namespace se
#endif // Include guard
Observable.cpp
#include <cstdlib>
#include <cassert>
#include "Observable.h"
namespace se {
template <typename T>
void Observable<T>::addObserver(Observer<T>* observer) {
m_observers.push_back(observer);
}
template <typename T>
void Observable<T>::removeObserver(Observer<T>* observer) {
assert(observer->getId().get() < m_observers.size());
for (size_t i = 0; i < m_observers.size(); ++i) {
if (observer->getId() == m_observers.at(i)->getId()) {
m_observers.erase(m_observers.begin() + i);
}
}
}
template <typename T>
void Observable<T>::notify(const T& topic) {
for (size_t i = 0; i < m_observers.size(); ++i) {
m_observers.at(i)->onNotify(topic);
}
}
} // namespace se
The problem isn't a circular dependency one as Obervable<T>
is not circularly dependent (UID.h only includes STL headers). I'm using cmake to make and gcc to compile/link.
I hope you can help me out as I have spent over 7 hours trying to resolve this...