flyfish 2014-12-16
编写一个Singleton类
class Singleton(){}; 该类是空类
经过编译器处理后,C++编译器默认编写的函数代码如下
class Singleton() { public: Singleton() {} // 1 构造函数 Singleton(const Singleton& s{} // 2 拷贝构造函数 ~Singleton(){} // 3 析构函数 Singleton& operator=(const Singleton& s{} // 4 拷贝赋值函数 copy assignment };
1 禁止用户建立对象
将Singleton类的构造函数,拷贝构造函数,拷贝赋值函数 全部声明为private,这样用户都没有权力建立对象
private:
Singleton() {};
Singleton(Singleton const&);
void operator=(Singleton const&);
2 用户可以调用
利用public成员函数来进行访问
接口函数static Singleton& getInstance()
3 线程安全,保证对象的唯一
静态成员对象(static member objects )是不是对象的一部分
从C++11 开始 如果静态成员声明为thread_local,每一个线程都有这样的一个object,否则在整个程序中的静态成员对象只有一个实例,也就是在C++11 如果声明了静态成员,那么这个静态成员是线程安全的。
对于什么时候创建对象有两种方案供选择
Eager evaluation和Lazy Evaluation
Eager evaluation是在程序启动时就要创建对象
最快的计算就是不计算,需要的话就是开始创建对象,不需要就不创建对象这就是惰性求值(Lazy Evaluation)
Lazy Evaluation的目的就是要最小化计算机要做的工作。
C++ 11 + Lazy Evaluation
实现如下
class Singleton { public: static Singleton& getInstance() { static Singleton instance; return instance; } private: Singleton() {}; Singleton(Singleton const&); void operator=(Singleton const&); };
编译器不支持C++11,可以参考Boost的实现
代码在boost文件夹的位置
boost\core\noncopyable.hpp
boost\serialization\singleton.hpp
简化可以看的清楚些
class noncopyable { protected: noncopyable() {} ~noncopyable() {} private: noncopyable( const noncopyable& ); noncopyable& operator=( const noncopyable& ); }; typedef noncopyable_::noncopyable noncopyable; class singleton_module : public boost::noncopyable { private: static bool & get_lock(){ static bool lock = false; return lock; } public: static void lock(){ get_lock() = true; } static void unlock(){ get_lock() = false; } static bool is_locked() { return get_lock(); } }; template<class T> class singleton_wrapper : public T { public: static bool m_is_destroyed; ~singleton_wrapper(){ m_is_destroyed = true; } }; template<class T> bool detail::singleton_wrapper< T >::m_is_destroyed = false; template <class T> class singleton : public singleton_module { private: static T & instance; static void use(T const &) {} static T & get_instance() { static detail::singleton_wrapper< T > t; BOOST_ASSERT(! detail::singleton_wrapper< T >::m_is_destroyed); use(instance); return static_cast<T &>(t); } public: static T & get_mutable_instance(){ BOOST_ASSERT(! is_locked()); return get_instance(); } static const T & get_const_instance(){ return get_instance(); } static bool is_destroyed(){ return detail::singleton_wrapper< T >::m_is_destroyed; } }; template<class T> T & singleton< T >::instance = singleton< T >::get_instance();