欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

boost的单件工具类

程序员文章站 2024-03-14 11:19:10
...

源码见文章底部。

class singleton<T> 声明了一个静态引用     static T & m_instance;

这个静态引用是用来干嘛的呢?注意到该文件末尾有如下代码:

template<class T>
T & singleton< T >::m_instance = singleton< T >::get_instance();
读到这里应该大概能理解了,该引用只是为了使用static的特性,该全局对象在程序初始化之前就进行了实例化了对象。

单例函数get_instance()方位属性为private。内部有如下定义         class singleton_wrapper : public T {};将T的构造函数保护了起来。先将静态成员赋值然后在堆中构造对象,静态成员指向他。

is_destroyed()主要作用是对生命周期做控制管理。

而template <class T>   static void use(T const *) 只是为了消除未初始化的警告,可参考另一工具类

boost::template <typename... Ts>void ignore_unused()的使用。最后调用构造生成实例对象并返回其引用。

        // refer to instance, causing it to be instantiated (and
        // initialized at startup on working compilers)
        BOOST_ASSERT(! is_destroyed());

        // note that the following is absolutely essential.
        // commenting out this statement will cause compilers to fail to
        // construct the instance at pre-execution time.  This would prevent
        // our usage/implementation of "locking" and introduce uncertainty into
        // the sequence of object initializaition.
        use(& m_instance);

        if (!t)
            t = new singleton_wrapper;
        return static_cast<T &>(*t);
class singleton<T>的析构函数负责清理资源。

下面的代码为测试简单的简单的静态对象单例模式与boost::serialization::singleton<T>的区别

#include <boost/serialization/singleton.hpp>
#include <iostream>
template<typename T>
class singleton_test
{
private:
	T tt;
public:
	T& get_instance() { return tt; }
};

class TEST_CLASS1
{
public:
	TEST_CLASS1() { std::cout << __FUNCTION__ << std::endl; }
	~TEST_CLASS1(){ std::cout << __FUNCTION__ << std::endl; }

	void print() { std::cout << "hello, im TEST_CLASS1" << std::endl; }
};

class TEST_CLASS2
{
public:
	TEST_CLASS2() { std::cout << __FUNCTION__ << std::endl; }
	~TEST_CLASS2() { std::cout << __FUNCTION__ << std::endl; }

	void print() { std::cout << "hello, im TEST_CLASS2" << std::endl; }
};

int main()
{
	std::cout << "begin main:" << std::endl;
	boost::serialization::singleton<TEST_CLASS2> t2;
	singleton_test<TEST_CLASS1> t1;


	t1.get_instance().print();
	t2.get_mutable_instance().print();

	std::cout << "end main:" << std::endl;
}
测试结果如图:

boost的单件工具类

boost的单件工具类

可知boost库的单件在程序入口点(main)之前已经完成构造。而两者析构顺序与声明顺序相关(逆序)。


boost库的单件源码(版本boost_1_66_0)

template <class T>
class singleton : public singleton_module
{
private:
    static T & m_instance;
    // include this to provoke instantiation at pre-execution time
    static void use(T const *) {}
    static T & get_instance() {
        // use a wrapper so that types T with protected constructors
        // can be used
        class singleton_wrapper : public T {};

        // Use a heap-allocated instance to work around static variable
        // destruction order issues: this inner singleton_wrapper<>
        // instance may be destructed before the singleton<> instance.
        // Using a 'dumb' static variable lets us precisely choose the
        // time destructor is invoked.
        static singleton_wrapper *t = 0;

        // refer to instance, causing it to be instantiated (and
        // initialized at startup on working compilers)
        BOOST_ASSERT(! is_destroyed());

        // note that the following is absolutely essential.
        // commenting out this statement will cause compilers to fail to
        // construct the instance at pre-execution time.  This would prevent
        // our usage/implementation of "locking" and introduce uncertainty into
        // the sequence of object initializaition.
        use(& m_instance);

        if (!t)
            t = new singleton_wrapper;
        return static_cast<T &>(*t);
    }
    static bool & get_is_destroyed(){
        static bool is_destroyed;
        return is_destroyed;
    }

public:
    BOOST_DLLEXPORT static T & get_mutable_instance(){
        BOOST_ASSERT(! is_locked());
        return get_instance();
    }
    BOOST_DLLEXPORT static const T & get_const_instance(){
        return get_instance();
    }
    BOOST_DLLEXPORT static bool is_destroyed(){
        return get_is_destroyed();
    }
    BOOST_DLLEXPORT singleton(){
        get_is_destroyed() = false;
    }
    BOOST_DLLEXPORT ~singleton() {
        if (!get_is_destroyed()) {
            delete &(get_instance());
        }
        get_is_destroyed() = true;
    }
};

template<class T>
T & singleton< T >::m_instance = singleton< T >::get_instance();

} // namespace serialization
} /


相关标签: boost

上一篇: C11-noexcept

下一篇: envoy的热重启