为什么do_nothing方法需要C ++单例实例化? [英] Why is the do_nothing method needed for C++ singleton instantiation?

查看:213
本文介绍了为什么do_nothing方法需要C ++单例实例化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我翻阅了 http:/ /www.boost.org/doc/libs/1_47_0/boost/pool/detail/singleton.hpp

我的问题:因为create_object是一个静态成员的singleton_default类的构造函数应该在main之前调用。从object_creator的构造函数,调用singleton_default :: instance,这确保obj在main之前被实例化。我不遵循的是需要do_nothing方法。文档提到它强制create_object的实例化,但不是类的静态成员应该在main开始之前初始化?通过那个令牌应该singleton_default :: create_object实例化不够好吗?

My question: since create_object is a static member of class singleton_default its constructor should be called before main. From the constructor of object_creator, singleton_default::instance is called, which makes sure obj is instantiated before main. What I don't follow is the need for the do_nothing method. The documentation mentions it forces the instantiation of create_object but are not static members of class supposed to be initialized before main starts? By that token should singleton_default::create_object instantiation not be good enough?

这里是代码

// 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方法,但是在main之前停止了对象实例化。

I tried removing the do_nothing method, but that stopped the object instantiation before main.

推荐答案

您必须在 部分查看标准3.6.2非局部变量的初始化

第2点的原则:


具有静态存储持续时间的变量...)在任何其他初始化之前应该是零初始化的

Variables with static storage duration (...) shall be zero-initialized before any other initialization takes place.

执行常量初始化:(...)

Constant initialization is performed: (...)

一起,零初始化和常量初始化称为
静态初始化;所有其他初始化是动态
初始化。在任何
动态初始化之前应执行静态初始化。具有静态存储持续时间的
非本地变量的动态初始化是有序的或
无序的。明确的专门类模板的定义static
数据成员已经排序初始化。

Together, zero-initialization and constant initialization are called static initialization; all other initialization is dynamic initialization. Static initialization shall be performed before any dynamic initialization takes place. Dynamic initialization of a non-local variable with static storage duration is either ordered or unordered. Definitions of explicitly specialized class template static data members have ordered initialization.

然后在第4点, (你的单例需要一个动态初始化):

Then in point 4, the explanation for your question (your singleton requiring a "dynamic intialisation") :


具有静态存储持续时间的局部变量在main的
第一个语句之前完成。如果初始化被推迟到main的第一个语句之后的某个
时间点,它将在
之前发生,在同一个
翻译单元中定义的任何函数或变量的第一个odr使用

It is implementation-defined whether the dynamic initialization of a non-local variable with static storage duration is done before the first statement of main. If the initialization is deferred to some point in time after the first statement of main, it shall occur before the first odr-use of any function or variable defined in the same translation unit as the variable to be initialized.

这个 do_nothing()使用和动态初始化的顺序。

This do_nothing() just ensures this first use and the order of the dynamic initialisation.

不会有 do_nothing(),全局静态 create_object 实例()之前, 将不需要初始化,而静态 obj 只会在第一次调用时初始化,即在 main()开始之后。

Wouldn't you have the do_nothing(), the global static create_object() wouldn't be needed to be initalized before your first call of instance(), and the static obj inside this function would only be initialized at first call, i.e. after the start of main().

这篇关于为什么do_nothing方法需要C ++单例实例化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆