面试--singleton--被鄙视了
周四去某公司面试,被问道C++的单例模式的实现,现场手写,我写了一个返回函数局部静态对象的例程,
然后就被鄙视了。。。
然后回家股沟,原来那种写法不是线程安全的,重新写了一遍,求拍砖。
class CSingeton{private: class CAssist { public: CAssist(void) { m_lock = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; if (NULL == mp_inst) { pthread_mutex_lock(&m_lock); if (NULL == mp_inst) { mp_inst = new CSingeton(); } pthread_mutex_unlock(&m_lock); } } ~CAssist(void) { if (NULL != mp_inst) { delete mp_inst; mp_inst = NULL; } } CSingeton *mp_inst; pthread_mutex_t m_lock; };public: static CSingeton &GetInst(void) { static CAssist sm_assist; return *sm_assist.mp_inst; } void PrintX(void) const { cout << m_x << endl; }private: CSingeton(void) : m_x(33) { cout << "singleton constructed" << endl; } ~CSingeton(void) { cout << "singleton destructed" << endl; } CSingeton(CSingeton const &r); CSingeton &operator =(CSingeton const &r); int m_x;};#include <boost/shared_ptr.hpp>#include <boost/function.hpp>#include <boost/bind.hpp>#include <windows.h>using std::cout;using std::endl;namespace Scan{ typedef unsigned int uint32; /** @brief 类分配器 有特殊用处的类应该特化它 */ template<typename T> struct ClassAllocator { static T* alloc() { return new T; } static void unalloc(T *p) { delete p; } }; /** @brief 资源管理类 保证在析构时调用某函数 */ class ResGuard { public: /** @brief 构造函数 @param p 调用函数的参数; 可以是类指针 @param f 要调用的函数; 可以是类成员函数 */ template<typename T, typename FunType> ResGuard(FunType f, T *p): m_f(boost::bind(f, p)){} ~ResGuard() { m_f(); } private: /** @brief 用boost::function来解耦 */ boost::function<void(void)> m_f; }; class ISyncObject { public: virtual ~ISyncObject() = 0{} virtual bool lock(uint32 waitTime = -1) = 0; virtual void unlock() = 0; }; class SingleLocker { public: SingleLocker(ISyncObject *o): m_guard(&ISyncObject::unlock, o) { o->lock(); } SingleLocker(ISyncObject &o): m_guard(&ISyncObject::unlock, &o) { o.lock(); } private: ResGuard m_guard; }; namespace Windows { /** @brief 临界区对象 同一线程不会在同一对象上递归锁住; 即, 临界区对象对每个线程有计数 */ class CriticalSection: public ISyncObject { public: CriticalSection(); ~CriticalSection(); bool lock(uint32 waitTime = -1); void unlock(); private: CRITICAL_SECTION m_cs; }; CriticalSection::CriticalSection() { InitializeCriticalSection(&m_cs); } CriticalSection::~CriticalSection() { DeleteCriticalSection(&m_cs); } bool CriticalSection::lock(uint32 waitTime/* = -1*/) { EnterCriticalSection(&m_cs); return true; } void CriticalSection::unlock() { LeaveCriticalSection(&m_cs); } } /** @brief 单例模式 使用它有两个步骤: 1. 继承; class T: public Singleton<T>{} 2. 私有化构造函数, 并添加友元; friend struct classAllocator<T>; */ template<typename T, typename MutexType = Windows::CriticalSection> class ISingleton { public: static T& getSingleton() { return *getSingletonPtr(); } static T* getSingletonPtr() { static boost::shared_ptr<T> cs_object; if (cs_object.get() == NULL) { SingleLocker locker(cs_synObject); if (cs_object.get() == NULL) { cs_object = boost::shared_ptr<T>( ClassAllocator<T>::alloc(), &ClassAllocator<T>::unalloc); } } return cs_object.get(); } protected: ~ISingleton(){} private: static MutexType cs_synObject; }; template<typename T, typename MutexType> MutexType ISingleton<T, MutexType>::cs_synObject;};class A: public Scan::ISingleton<A>{public: void fun() { cout << "test" << endl; }private: friend struct Scan::ClassAllocator<A>; A(){}};int main(){ A::getSingletonPtr()->fun(); system("pause");return 0;}
[解决办法]
如果考虑new的异常安全的话,加上copy and swap技术更加好
[解决办法]