C++ 模板类中嵌套类的静态实例的初始化
我想这样做:C++ 模板类中嵌套类的静态实例的初始化,c++,templates,static,initialization,nested,C++,Templates,Static,Initialization,Nested,我想这样做: 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() {...} 模板 S类 { ... 甲级 { ~A(){cout未使用
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()
{...}
模板
S类
{
...
甲级
{
~A(){cout未使用模板中的静态对象
当你隐式实例化一个模板类时,只有被使用的类的部分被实例化。该标准指出C++中的静态数据成员。11节〈7.7.1〉8:< /P>
类模板的隐式实例化不会导致隐式实例化该类的任何静态数据成员
解决方案
您需要以某种方式引用静态对象的非模板代码,或者需要显式实例化模板
参考静态对象
由于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;
template <typename T>
class S
{
class A
{
friend S;
~A(){std::cout << "~A\n";}
static A & getInstance () {
static A obj;
return obj;
}
};
public:
void foo () { A::getInstance(); }
};
显式实例化模板
模板类的显式实例化将完全定义它,就像模板类已作为常规类编写一样。因此,将创建静态对象,而无需隐式引用它
template class S<int>;
模板类S;
关于单身模式
隐式实例化行为减少了膨胀
如果您使用的是单例代码,那么您观察到的行为实际上就是您想要的。您只希望创建实际使用的单例对象。这将防止未使用的代码不必要地占用程序中的资源
防止显式实例化的膨胀
由于需要防止程序的运行时膨胀,因此即使显式实例化了Singleton,也需要这样做。这自然是通过在返回它的方法中确定Singleton实例的范围来实现的
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;
template <typename T>
class S
{
class A
{
friend S;
~A(){std::cout << "~A\n";}
static A & getInstance () {
static A obj;
return obj;
}
};
public:
void foo () { A::getInstance(); }
};
模板
S类
{
甲级
{
朋友S;
~A(){std::cout答案取决于问题的“…”部分中所写的内容。下面是一个使用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();
}
#包括
使用名称空间std;
模板
S类
{
公众:
T-m;
甲级
{
公众:
(){谢谢你的回答,你是第一个。这很有帮助,但我想接受Willem的回答,因为你的声誉很高。对不起,但真的很感谢。@Tzu sz:没问题,你可以自由选择你认为最有帮助的答案。Singleton的代码在我的答案中发布。我使用嵌套类只是为了释放资源。@Tzu szz:当调用全局析构函数时,模板的静态成员将被析构函数。谢谢,这个问题来自Singleton的一个实现,您的回答提供了一个创建静态实例的好方法。Singleton的成员函数“getInstance”可以调用函数“say”。