加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 静态数据成员是否真的可以进行延迟初始化?

发布时间:2020-12-16 10:29:51 所属栏目:百科 来源:网络整理
导读:是否可以在真正需要时初始化Singleton的实例? 考虑从着名的“设计模式”中获取的这种模式: class Singleton {public: static Singleton* Instance();protected: Singleton();private: static Singleton* _instance;}Singleton* Singleton::_instance = 0;
是否可以在真正需要时初始化Singleton的实例?

考虑从着名的“设计模式”中获取的这种模式:

class Singleton {
public:
   static Singleton* Instance();
protected:
   Singleton();
private:
   static Singleton* _instance;
}

Singleton* Singleton::_instance = 0; // unit.cpp

static Singleton* Singleton::Instance() {
   if (_instance == 0) {
       _instance = new Singleton;
   }
   return _instance;
}

现在,我认为那里的模式存在问题,如果有人希望将库中的Singleton提供给其他人:如果用户从另一个编译单元调用Singleton :: Instance()(例如在静态数据成员初始化期间,例如)在初始化_instance之前,接下来调用Singleton :: Instance()可能会创建Singleton的另一个实例,并产生不需要的结果,因为_instance可能首先被初始化为0.

我认为一种解决方案是以这种方式初始化_instance:

Singleton* Singleton::_instance = Singleton::Instance();

无论如何,这使得初始化对于那些不需要调用Singleton :: Instance()来初始化其静态数据的人来说不是“懒惰”.

是否有更好的解决方案,以便在需要Singleton实例时可以进行初始化?

解决方法

动态初始化之前发生静态初始化

你引用的单例解决方案有效

Singleton* Singleton::_instance = 0;

描述了静态初始化(即在这种情况下为零初始化,但如果使用的话,常量初始化也会起作用),这保证在任何动态初始化之前(因此在运行任何代码之前)发生.这里保证了静态初始化的所有要求,因为_instance是内置类型(指针)的全局变量,并用零初始化.

你提供的另一个解决方案没有改变任何重要的东西,因为在调用其他模块的代码之前,仍然只保证_instance的零初始化,因为Singleton :: Instance调用的初始化是动态的,因此受制于static initialization order fiasco.

实施 – 数据部分

注意:静态初始化通常通过在变量的data segment中存储变量的值来实现,该变量的值是计算的编译时间.

术语,标准报价

虽然大多数程序员(包括Bjarne Stroustrup)调用原始单例实现“编译时初始化”中使用的初始化样式,但标准将其称为“静态初始化”,而不是“动态初始化”(这通常称为运行初始化)时间).见C++0x draft 3.6.2(缩写,强调我的):

3.6.2 Initialization of non-local variables [basic.start.init]

… Non-local variables with static storage duration are initialized
as a consequence of program initiation. … as follows.

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

Constant initialization is performed:

  • if an object with static or thread storage duration is not initialized by a constructor call and if every full-expression that appears in its initializer is a constant expression.

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.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读