C++ 强制生成模板基函数
我使用好奇的循环模板模式(CRTP)来提供功能,这需要为基类生成静态函数。通常,我忘记显式地实例化函数,这会导致错误的行为(没有生成函数)。下面显示了一个单例基类的简单示例C++ 强制生成模板基函数,c++,templates,crtp,C++,Templates,Crtp,我使用好奇的循环模板模式(CRTP)来提供功能,这需要为基类生成静态函数。通常,我忘记显式地实例化函数,这会导致错误的行为(没有生成函数)。下面显示了一个单例基类的简单示例 #include <iostream> template <class T> class Singleton { public: static const T& InstanceGet() { if (!pInstance) { pInstance = new T; }
#include <iostream>
template <class T>
class Singleton {
public:
static const T& InstanceGet() {
if (!pInstance) { pInstance = new T; }
return *pInstance;
}
static int InstanceDestroy() __attribute__((destructor));
protected:
Singleton() = default;
Singleton(Singleton const &) = delete;
Singleton& operator=(Singleton const &) = delete;
private:
static T* pInstance;
};
template <class T>
int Singleton<T>::InstanceDestroy() {
if (pInstance) {
delete pInstance;
pInstance = nullptr;
}
return 0;
}
template <class T>
T* Singleton<T>::pInstance = nullptr;
class Test : public Singleton<Test> {
friend class Singleton<Test>;
};
// Explicit instantiate destructor (otherwise not called)
// template int Singleton<Test>::InstanceDestroy();
int main(int argc, char* argv[]) {
const Test& pTest = Test::InstanceGet();
return 0;
}
#包括
模板
单件阶级{
公众:
静态常量T&InstanceGet(){
如果(!pInstance){pInstance=new T;}
返回*pInstance;
}
静态int InstanceDestroy()_属性__((析构函数));
受保护的:
Singleton()=默认值;
单例(单例常量&)=删除;
单例&运算符=(单例常量&)=delete;
私人:
静态T*pInstance;
};
模板
int Singleton::InstanceDestroy(){
if(pInstance){
删除站姿;
pInstance=nullptr;
}
返回0;
}
模板
T*Singleton::pInstance=nullptr;
班级测试:公共单身{
朋友班单身;
};
//显式实例化析构函数(否则不调用)
//模板int Singleton::InstanceDestroy();
int main(int argc,char*argv[]){
常量Test&pTest=Test::InstanceGet();
返回0;
}
如果我忘记显式实例化int Singleton::InstanceDestroy()
,则在卸载库时不会生成和调用该函数。问题:是否有自动方式确保生成此类功能
我找到了一种方法,但这在启动期间引入了一个虚拟调用。将以下常量添加到基类
const int atexit = Singleton<T>::InstanceDestroy();
const int-atexit=Singleton::InstanceDestroy();
这不是很优雅
最后,我应该提到,问题不在于如何处理单身人士。我使用上面的模式来创建对象发布者和订阅者、垃圾收集等
提前感谢而不是
\uuuu属性((析构函数))
hack,我会尝试用一个花园式析构函数声明一个内部类,然后实例化内部类的一个静态类实例。你真的需要重置singleton吗?否则迈尔斯的单身汉更好。我尽量避免迈尔斯的单身汉。我们使用一个旧的编译器,它不会使用Meyers singleton生成线程安全的代码(示例不是线程安全的)。另外,我希望避免干扰已经注册在一个巨大静态数据库中的许多单身人士application@SamVarshavchik不太可能。我希望避免静态变量,因为静态变量会自动插入到已经无限长的函数指针列表中<代码>\uuuu属性(析构函数))不是hack-这是在调用之前注册函数的正确方法unloading@SamVarshavchik类的静态实例不会导致在列表中插入指向析构函数的函数指针,其中许多其他函数是使用atexit
注册的,即应用程序退出而不是库卸载