Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 模板类中嵌套类的静态实例的初始化_C++_Templates_Static_Initialization_Nested - Fatal编程技术网

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”。