I read a lot of topics about templates classes, on stackoverflow and other websites, but all I understood and tried did not work, so please let me expose you my code, if you could tell me what I am doing wrong it could be very nice.
NB: I know about bad practice of using Singleton, but please it is not the talk, please assume it is just an academic exercice to work with template classes.
Library project:
// fsingleton.h
#include <QObject>
#if defined(LIB_LIBRARY)
# define FCORE_EXPORT Q_DECL_EXPORT
#else
# define FCORE_EXPORT Q_DECL_IMPORT
#endif
template<typename T>
class FCORE_EXPORT FSingleton
{
public:
static T *instance();
static void kill();
protected:
static T *m_instance;
FSingleton();
virtual ~FSingleton();
private:
Q_DISABLE_COPY(FSingleton)
};
template<typename T>
T *FSingleton<T>::m_instance = Q_NULLPTR;
template<typename T>
T *FSingleton<T>::instance()
{
if (m_instance == Q_NULLPTR) {
m_instance = new T();
}
return m_instance;
}
template<typename T>
void FSingleton<T>::kill()
{
delete m_instance;
m_instance = Q_NULLPTR;
}
template<typename T>
FSingleton<T>::FSingleton() {}
template<typename T>
FSingleton<T>::~FSingleton() {}
Here I am in a library project, so LIB_LIBRARY
is defined when building, so we have Q_DECL_EXPORT
, and the library is built sucessfully.
Executable project:
// testsingleton.h
#include "fsingleton.h"
class TestSingleton : public FSingleton<TestSingleton>
{
public:
TestSingleton();
virtual ~TestSingleton();
};
// testsingleton.cpp
#include "testsingleton.h"
TestSingleton::TestSingleton() {}
TestSingleton::~TestSingleton() {}
// tst_utfsingleton.cpp - it is a unit test source file following Qt Test template, I write it as a simple main.cpp function to simplify the example
#include "testsingleton.h"
void main()
{
TestSingleton* ptr1 = TestSingleton::instance();
}
This executable fails to compile on linking, and gives the following output:
../debug/obj/tst_utfsingleton.o: In function `FSingleton<TestSingleton>::instance()':
../lib/fsingleton.h:63: undefined reference to `__imp__ZN10FSingletonI13TestSingletonE10m_instanceE'
../lib/fsingleton.h:64: undefined reference to `__imp__ZN10FSingletonI13TestSingletonE10m_instanceE'
../lib/fsingleton.h:68: undefined reference to `__imp__ZN10FSingletonI13TestSingletonE10m_instanceE'
../debug/obj/testsingleton.o: In function `FSingleton<TestSingleton>::FSingleton()':
../lib/fsingleton.h:79: undefined reference to `__imp__ZTV10FSingletonI13TestSingletonE'
../debug/obj/testsingleton.o: In function `FSingleton<TestSingleton>::~FSingleton()':
../lib/fsingleton.h:88: undefined reference to `__imp__ZTV10FSingletonI13TestSingletonE'
../debug/obj/testsingleton.o: In function `FSingleton<TestSingleton>::~FSingleton()':
../lib/fsingleton.h:88: undefined reference to `__imp__ZTV10FSingletonI13TestSingletonE'
collect2.exe: error: ld returned 1 exit status
I dot not realy understand why all this undefined references. The m_instance
member is declared into the FSingleton
class and initialized just after the class definition, in the fsingleton.h
. I do not see what I am doing wrong, could you help me please?
Regards
Ok so due to the answer of @drescherjm the issue is solved.
What I understand it is that template classes are generated during compile time, depending on the needed instantiations. So, in my case I mark the template class FSingleton
as __declspec(dllexport)
when building library, but there is no instantiation in my library, so nothing is exported. Then, compiling the executable, the class is marked as __declspec(dllimport)
but there is consequently nothing to import, because nothing was built during library build, because the instantiation FSingleton<TestSIngleton>
is done into the executable source code.
Do not hesitate to fix my words if I said something wrong ^^
Thanks again @drescherjm
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.