C++ 链接器在某些情况下会抱怨模板类静态对象成员的引用未定义
我是模板编程新手。在使用模板实现singleton类时,我发现在某些情况下(如下所示),链接器会抱怨错误:C++ 链接器在某些情况下会抱怨模板类静态对象成员的引用未定义,c++,templates,object,static,definition,C++,Templates,Object,Static,Definition,我是模板编程新手。在使用模板实现singleton类时,我发现在某些情况下(如下所示),链接器会抱怨错误: undefined reference to `Singleton<Test>::_lock' Singleton::\u lock的未定义引用 然而,如果我改变下面的陈述 template<> Mutex Singleton<Test>::_lock; template Mutex Singleton::\u lock; 到 模板互斥体单例::
undefined reference to `Singleton<Test>::_lock'
Singleton::\u lock的未定义引用
然而,如果我改变下面的陈述
template<> Mutex Singleton<Test>::_lock;
template Mutex Singleton::\u lock;
到
模板互斥体单例::_锁(1);
它编译和运行时不会出错
有人能帮我解释一下为什么在下面的情况下编译失败吗
#include <iostream>
#include <pthread.h>
class Mutex {
public:
Mutex(){ pthread_mutex_init(&mMutex, NULL); }
Mutex(int dummy){ pthread_mutex_init(&mMutex, NULL); }
~Mutex(){ pthread_mutex_destroy(&mMutex); }
Mutex(const Mutex&) = delete;
Mutex& operator = (const Mutex&) = delete;
int lock(){ return -pthread_mutex_lock(&mMutex); }
void unlock(){ pthread_mutex_unlock(&mMutex); }
// Manages the mutex automatically. It'll be locked when Autolock is
// constructed and released when Autolock goes out of scope.
class Autolock {
public:
explicit Autolock(Mutex& mutex) : mLock(mutex) { mLock.lock(); }
~Autolock() { mLock.unlock(); }
private:
Mutex& mLock;
};
private:
pthread_mutex_t mMutex;
};
template <typename T>
class Singleton: {
public:
static T& Instance() {
Mutex::Autolock _l(_lock);
if(nullptr == _instance) {
_instance = new T();
}
return *_instance;
}
virtual ~Singleton(){}
Singleton() = default;
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
private:
static T* _instance;
static Mutex _lock;
};
class Test: public Singleton<Test> {
public:
void dis() {std::cout << "hi" << std::endl;}
};
template<> Mutex Singleton<Test>::_lock;
template<> Test* Singleton<Test>::_instance(nullptr);
template class Singleton<Test>;
int main()
{
Test::Instance().dis();
return 0;
}
#包括
#包括
类互斥{
公众:
Mutex(){pthread_Mutex_init(&mMutex,NULL);}
互斥(int-dummy){pthread_-Mutex_-init(&mMutex,NULL);}
~Mutex(){pthread_Mutex_destroy(&mMutex);}
互斥(const Mutex&)=删除;
互斥体&运算符=(常量互斥体&)=删除;
int lock(){return-pthread_mutex_lock(&mMutex);}
void unlock(){pthread_mutex_unlock(&mMutex);}
//自动管理互斥锁。自动锁定时将锁定互斥锁
//当Autolock超出范围时构造并释放。
类自动锁定{
公众:
显式自动锁(互斥锁和互斥锁):mLock(互斥锁){mLock.lock();}
~Autolock(){mLock.unlock();}
私人:
互斥锁&mLock;
};
私人:
pthread_mutex_t mMutex;
};
模板
单身人士类别:{
公众:
静态T&实例(){
互斥锁::自动锁定(锁定);
if(nullptr==\u实例){
_实例=新的T();
}
返回*\u实例;
}
虚拟~Singleton(){}
Singleton()=默认值;
单例(const Singleton&)=删除;
单例&运算符=(常量单例&)=delete;
私人:
静态T*_实例;
静态互斥锁;
};
班级测试:公共单身{
公众:
void dis(){std::cout与您使用的相同:template Test*Singleton::_instance(nullptr);
?是的。template Test*Singleton:_instance(nullptr)没有问题
,编译器没有报告任何有关\u实例的错误。顺便说一句,我在ubuntu build env中使用了gcc。您是否已将原始代码拆分到.cpp和.h文件中。不幸的是,对于模板,所有tempate代码都必须放在标题中。
#include <iostream>
#include <pthread.h>
class Mutex {
public:
Mutex(){ pthread_mutex_init(&mMutex, NULL); }
Mutex(int dummy){ pthread_mutex_init(&mMutex, NULL); }
~Mutex(){ pthread_mutex_destroy(&mMutex); }
Mutex(const Mutex&) = delete;
Mutex& operator = (const Mutex&) = delete;
int lock(){ return -pthread_mutex_lock(&mMutex); }
void unlock(){ pthread_mutex_unlock(&mMutex); }
// Manages the mutex automatically. It'll be locked when Autolock is
// constructed and released when Autolock goes out of scope.
class Autolock {
public:
explicit Autolock(Mutex& mutex) : mLock(mutex) { mLock.lock(); }
~Autolock() { mLock.unlock(); }
private:
Mutex& mLock;
};
private:
pthread_mutex_t mMutex;
};
template <typename T>
class Singleton: {
public:
static T& Instance() {
Mutex::Autolock _l(_lock);
if(nullptr == _instance) {
_instance = new T();
}
return *_instance;
}
virtual ~Singleton(){}
Singleton() = default;
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
private:
static T* _instance;
static Mutex _lock;
};
class Test: public Singleton<Test> {
public:
void dis() {std::cout << "hi" << std::endl;}
};
template<> Mutex Singleton<Test>::_lock;
template<> Test* Singleton<Test>::_instance(nullptr);
template class Singleton<Test>;
int main()
{
Test::Instance().dis();
return 0;
}