http://www.cnblogs.com/kex1n/archive/2011/04/05/2006194.html

effectie c++的条款4中提到:

(global对象,定义在namespace内的对象,class内的static对象,函数内的static对象,file作用域内的 static对象)统称为static对象。其中函数内的static对象又叫local static object, 其他的叫non-local static object。

non-local static object的初始化顺序是没有定义的,local static object在函数第一次调用时构造初始化。

还有:non-local static object会在main函数之前被初始化。

#pragma once
#include <iostream>
using namespace std;

class Foo
{
public:
    Foo()
    {
        cout<<"Foo create!"<<endl;
    }
};

class Test
{
public:
    Test() {}
    Foo GetX() const{ return x_;}
private:
    static Foo x_;
};

Foo Test::x_;

即使在main函数中未初始化Test对象,仍会看到Foo Create的提示,所以non-local static object在main函数之前初始化的。

普通的singleton模式:

#pragma once
template<typename T>
class Singleton_
{
public:
    static T&Instance()
    {

   static T t_;
        return t_;
    }
private:
    Singleton_() {}
};

多线程的时候此方法不给力,可以用加锁的办法,参见ACE实现的双重加锁优化的singleton实现。或要求使用者在main的早期或多线程环境之前把所有单件各调用一次instance()

由于non-local static object是在main之前初始化的,默认进入main函数之前只有主线程运行,则有如下写法

#pragma once

template<typename T>
class Singleton_
{
public:
    static T&Instance()
    {
        return t_;
    }

private:
    Singleton_() {}

static T t_;
};

template <typename T> T Singleton_<T>::t_;

这样实现的问题是,无法预知对象的生成的顺序,如果多个单件对象有初始化次序要求会出现问题,比如一个单件构造函数中会调用另一个单件的instance(),而那个单件还没有构造。

Boost的实现可以解决这两个问题。

下面看boost的singleton实现:

class Widget
{
public:
    Widget()
    {
        cout<<"Widget Creat"<<endl;
    }
};

template <typename T>
struct Singleton
{

private:
    struct object_creator
    {
        object_creator()
        {
            Singleton<T>::instance();
        }

inline void do_nothing()const
        {}
    };

static object_creator create_object;

Singleton () {}

public:
    typedef T object_type;
    static object_type& instance()
    {
        static object_type obj;
        create_object.do_nothing();
        return obj;
    }
};

//声明一个全局变量template <typename T> Singleton<T>::create_object
typename Singleton<T>::object_creator       Singleton<T>::create_object;

int main()
{
    Widget& w = Singleton<Widget>::instance();

return 0;
}

没有使用锁机制,而是充分利用了C++的语言特性较好的解决了多线程情况下使用singleton的问题。
boost的singleton的实现基于以下假设:良好的设计在进入main函数之前应该是单线程的。
我们可以使用全局变量的方式来设计singleton,并且保证在使用该singleton之前其已经被正确的初始化。

在进入main之前,唯一的主线程开始构造Singleton<T>::create_object,在其构造函数之内调用
Singleton的instance函数,并在该函数内生成Singleton对象,至于函数donoting(),去掉之后照样可以通过编译,我想原
因可能是为了再次保证singleton的初始化完全成功。

[转] boost库的Singleton的实现以及static成员的初始化问题的更多相关文章

  1. (七)boost库之单例类

    (七)boost库之单例类 一.boost.serialzation的单件实现 单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例类的特殊类.通过单例模式可以保证系统中一个类只有一 ...

  2. 新手,Visual Studio 2015 配置Boost库,如何编译和选择,遇到无法打开文件“libboost_thread-vc140-mt-gd-1_63.lib“的解决办法

    1,到官网下载最新的boost,www.boost.org 这里我下载的1-63版本. 2,安装,解压后运行bootstrap.bat文件.稍等一小会就OK. 3,编译boost库.注意一定要使用VS ...

  3. vs2013给项目统一配置boost库

    1.打开项目,然后点击菜单中的 视图->其他窗口->属性管理器 2. 打开属性管理器,点击项目前的箭头,展开项目,找到debug或者release下面的Microsoft.Cpp.Win3 ...

  4. [C/C++] C/C++延伸学习系列之STL及Boost库概述

    想要彻底搞懂C++是很难的,或许是不太现实的.但是不积硅步,无以至千里,所以抽时间来坚持学习一点,总结一点,多多锻炼几次,相信总有一天我们会变得"了解"C++. 1. C++标准库 ...

  5. dev c++ Boost库的安装

    dev c++ 的boost库的安装步骤 然后点击“check for updates”按钮 最后点击“Download selected”按钮,下载完成后安装.... 给dev添加boost库文件, ...

  6. vs配置boost库

    步骤: 1.在boost官网下载boost版本,以1.59.0为例. 2.解压,解压后可看到文件夹下有个bootstrap.bat文件. 注意: 如果有以下error: 'cl' 不是内部或外部命令, ...

  7. windows下安装boost库

    工作中现在会接触boost,所以我计划两个月之内努力熟悉一下boost.今天在自己win10系统上尝试安装了boost库,下面把遇到的问题总结一下: 1. 下好1.61版本库,在boost目录下运行b ...

  8. ubuntu 下安装boost库

    ubuntu下安装boost库,,在网上试了一些其他人推荐的libboost-dev 但是会缺少,编译程序会报错: /usr/bin/ld: cannot find -lboost_serializa ...

  9. linux下编译安装boost库

    linux下编译安装boost库 linux下编译安装boost库 1.下载并解压boost 1.58 源代码 下载 解压 2.运行bootstrap.sh 3.使用b2进行构建 构建成功的提示 4. ...

随机推荐

  1. Asp.net GridView 72般绝技

    快速预览:GridView无代码分页排序GridView选中,编辑,取消,删除GridView正反双向排序GridView和下拉菜单DropDownList结合GridView和CheckBox结合鼠 ...

  2. PHP常用代码:

    1.$array=explode(separator,$string); //字符串->数组 2.$string=implode(glue,$array);//数组->字符串 3.file ...

  3. TatukGIS - GisDefs - ChangeDir 函数

    函数名称  ChangeDir 所在单元  GisDefs 函数原型  function ChangeDir(const _path: String): String;   函数说明 如果 _path ...

  4. Linux 环境下自动化测试工具,Redhat dogtail的安装

    dogtail基于Accessibility(a11y)的GUI图形界面测试工具和自动化框架可以与linux桌面应用程序进行交互操作. dogtail是用Python语言写的.dogtail的测试脚本 ...

  5. TF-IDF与余弦相似性的应用

    类似的算法已经被写成了工具,比如基于Java的Classifier4J库的SimpleSummariser模块.基于C语言的OTS库.以及基于classifier4J的C#实现和python实现.

  6. BZOJ 1031 字符加密

    Description 喜欢钻研问题的JS 同学,最近又迷上了对加密方法的思考.一天,他突然想出了一种他认为是终极的加密办法:把需要加密的信息排成一圈,显然,它们有很多种不同的读法.例如下图,可以读作 ...

  7. 栈和队列的面试题Java实现

    栈和队列: 面试的时候,栈和队列经常会成对出现来考察.本文包含栈和队列的如下考试内容: (1)栈的创建 (2)队列的创建 (3)两个栈实现一个队列 (4)两个队列实现一个栈 (5)设计含最小函数min ...

  8. linux内核空间与用户空间信息交互方法

    linux内核空间与用户空间信息交互方法     本文作者: 康华:计算机硕士,主要从事Linux操作系统内核.Linux技术标准.计算机安全.软件测试等领域的研究与开发工作,现就职于信息产业部软件与 ...

  9. 自己动手实现Queue

    前言: 看到许多面经说,有时候面试官要你自己当场用模板写出自己的vector容器.于是,我也琢磨着怎么自己动手写一个,可是本人才刚刚学C++模板编程不久,会的不多.不过,我恰好在C++ Primer上 ...

  10. ural-1099-Work Scheduling(裸带花树)

    题意: 有N个人,有限对的人可以在一起工作,问最多能有多少对. 分析: 任意图的最大匹配 // File MAXName: 1099.cpp // Author: Zlbing // Created ...