2014-11-02 150 views
1

我去的文件在从http://www.boost.org/doc/libs/1_47_0/boost/pool/detail/singleton.hpp为什么C++单例实例化需要do_nothing方法?

我的问题:既然create_object是类的静态成员singleton_default它的构造应前主被调用。从object_creator的构造函数中,调用singleton_default :: instance,它确保obj在main之前实例化。我不遵循的是do_nothing方法的需要。文档中提到它强制实例化create_object,但不是应该在main启动之前初始化的类的静态成员?通过该标记应该singleton_default :: create_object实例化不够好?

下面的代码

// T must be: no-throw default constructible and no-throw destructible 
template <typename T> 
struct singleton_default 
{ 
    private: 
    struct object_creator 
    { 
     // This constructor does nothing more than ensure that instance() 
     // is called before main() begins, thus creating the static 
     // T object before multithreading race issues can come up. 
     object_creator() { singleton_default<T>::instance(); } 
     inline void do_nothing() const { } 
    }; 
    static object_creator create_object; 

    singleton_default(); 

    public: 
    typedef T object_type; 

    // If, at any point (in user code), singleton_default<T>::instance() 
    // is called, then the following function is instantiated. 
    static object_type & instance() 
    { 
     // This is the object that we return a reference to. 
     // It is guaranteed to be created before main() begins because of 
     // the next line. 
     static object_type obj; 

     // The following line does nothing else than force the instantiation 
     // of singleton_default<T>::create_object, whose constructor is 
     // called before main() begins. 
     create_object.do_nothing(); 

     return obj; 
    } 
}; 
template <typename T> 
typename singleton_default<T>::object_creator 
singleton_default<T>::create_object; 

我试图消除do_nothing方法,但在此之前主要是停止对象实例化。

回答

1

你必须看看的标准3.6.2初始化非局部变量

首先在第2点的原则:

变量与静态存储时间(...)应为零初始化 任何其他初始化发生之前。执行

常数初始化:(...)

总之,零初始化和常数初始化被称为 静态初始化;所有其他初始化都是动态的 初始化。在动态初始化发生之前,应执行静态初始化。具有静态存储持续时间的非局部变量的动态初始化可以是有序的,也可以是无序的 。明确专用类模板的定义static 数据成员已经命令初始化。

然后在4点,你的问题的解释(你单身,需要一个“动态intialisation”):

这是实现定义是否 非本地变量与动态初始化静态存储持续时间在 main的第一条语句之前完成。如果在main的第一个语句之后初始化被推迟到某个 时间点,它应该在 之前出现在同一个 翻译单元中定义的任何函数或变量的第一个odr-use作为要初始化的变量。

这个do_nothing()只是确保首次使用和动态初始化的顺序。

你会不会有do_nothing(),全局静态create_object()就不再需要你的instance()第一个电话,静态obj这个函数内部之前initalized只会在第一次调用初始化,启动之后即的main()

相关问题