初始化模板类中嵌套类的静态实例
The initialization of a static instance of a nested class in template class
我想这样做:
template <typename T>
class S
{
...
class A
{
~A(){cout << "~A";}
};
static A obj;
};
template <typename T>
typename S<T>::A S<T>::obj;
int main()
{...}
但是当程序启动时,不会创建嵌套类A的静态实例。"~A"则不会打印。问题出在哪里?
答案取决于"…"中写的内容部分问题。下面是一个使用gcc 4.8.1工作的完整示例;即打印"Ahello~A"如果您注释掉main()
中的代码,则程序不会产生任何结果。
#include <iostream>
using namespace std;
template <typename T>
class S
{
public:
T m;
class A
{
public:
A() {cout << "A";}
void say() {cout << "hello";}
~A(){cout << "~A";}
};
static A obj;
};
template <typename T>
typename S<T>::A S<T>::obj;
int main() {
S<int>::obj.say();
}
如果您在代码中不使用static,但仍然希望创建静态实例,则jxh给出的答案适用。在这种(不太可能的)情况下,您必须显式实例化模板类:template class S<int>;
模板中的静态对象未使用
当您隐式实例化模板类时,只有所使用的类的部分才会被实例化。该标准特别提到了C++中的静态数据成员。11§14.7.1&第;8:
类模板的隐式实例化不会导致该类的任何静态数据成员被隐式实例化。
解决方案
您将需要以某种方式引用静态对象的非模板代码,或者需要显式实例化模板。
参考静止物体
由于obj
是静态的,并且对S
是私有的,因此在S
中需要一些引用此对象的公共代码。例如,返回它的静态方法。
tempalte <typename T>
class S
{
//... define class A
static A obj;
public:
static A & get_obj () { return obj; }
};
template <typename T>
typename S<T>::A S<T>::obj;
然后,您可以从main()
调用此方法来隐式实例化obj
。
int main()
{
get_obj();
}
显式实例化模板
模板类的显式实例化将完全定义它,就好像该模板类是作为常规类编写的一样。因此,将创建静态对象,而无需隐式引用它。
template class S<int>;
关于Singleton模式
隐式实例化行为减少膨胀
如果您使用的是单例代码,那么您观察到的行为实际上就是您想要的。您只希望在实际使用的情况下创建您的singleton对象。这将防止未使用的代码不必要地占用程序中的资源。
防止显式实例化的膨胀
由于希望防止程序的运行时膨胀,因此即使Singleton被显式实例化,也希望这样做。这自然是通过在返回它的方法内部对单例实例进行范围界定来实现的
template <typename T>
class S
{
class A
{
friend S;
~A(){std::cout << "~An";}
static A & getInstance () {
static A obj;
return obj;
}
};
public:
void foo () { A::getInstance(); }
};
当静态实例的作用域在返回它的静态方法内时,不需要在类之外创建它的模板定义。静态实例仅在调用getInstance()
时创建。
- C++两个源文件之间共享的枚举的静态实例
- 宏为模板类静态实例生成有效的标识符
- 我可以在类头文件中定义一个类的const静态实例吗
- 类的静态实例不能调用私有成员函数.C++
- 第二个dll中的静态实例的破坏者未被调用
- 类的静态实例无法在程序退出时正确处理资源删除
- C++:外部类中内部类的静态实例
- 结构定义包含自身的静态实例
- 什么是C++中C#静态实例的等价物
- 父类包含子类C++的静态实例
- 在C++中创建静态实例的未解析外部
- 多个对象的静态实例变量-c++
- 在c++中,一旦程序退出,singleton(静态实例)就会被销毁,这是正确的原因
- 对从静态实例引用的类模板的静态成员的未定义引用
- 在类自身内部创建类的静态实例的正确方法
- 初始化模板类中嵌套类的静态实例
- 卸载c++插件中的静态实例变量
- 在c++ STL类型的静态实例上使用OpenMP threadprivate指令
- 我的类的静态实例函数不像我预期的那样工作
- 保留子类的中心列表,但避免静态实例