带有静态成员的 C++ 模板类 - 未定义的引用,而我的静态成员似乎已声明和初始化

问题描述

我在 stackoverflow 和其他网站上阅读了很多关于模板类的主题,但是我理解和尝试的所有内容都不起作用,所以请让我向您公开我的代码,如果您能告诉我我做错了什么,它可以非常好。

注意:我知道使用 Singleton 的不良做法,但这不是谈话,请假设这只是使用模板类的学术练习。


图书馆项目:

// 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() {}

这里我在一个库项目中,所以在构建时定义了LIB_LIBRARY,所以我们有Q_DECL_EXPORT,并且库构建成功。


可执行项目:

// 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();
}

此可执行文件无法在链接时编译,并提供以下输出

../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

我不太明白为什么所有这些未定义的引用。 m_instance 成员在 FSingleton 类中声明并在类定义之后初始化,在 fsingleton.h 中。我不明白我做错了什么,你能帮我吗?

问候

解决方法

好的,由于@drescherjm 的回答,问题解决了。

据我所知,模板类是在编译时生成的,具体取决于所需的实例化。 因此,在我的情况下,我在构建库时将模板类 FSingleton 标记为 __declspec(dllexport),但我的库中没有实例化,因此没有导出任何内容。 然后,在编译可执行文件时,类被标记为 __declspec(dllimport),但因此没有要导入的内容,因为在库构建期间没有构建任何内容,因为实例化 FSingleton<TestSIngleton> 已在可执行源代码中完成。>

如果我说错了,请不要犹豫纠正我的话^^

再次感谢@drescherjm