简体   繁体   中英

C++ template class with static member - Undefined reference, whereas my static member seems declared and initialized

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM