首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

面试-singleton-被鄙视了解决思路

2012-03-28 
面试--singleton--被鄙视了周四去某公司面试,被问道C++的单例模式的实现,现场手写,我写了一个返回函数局部

面试--singleton--被鄙视了
周四去某公司面试,被问道C++的单例模式的实现,现场手写,我写了一个返回函数局部静态对象的例程,
然后就被鄙视了。。。
然后回家股沟,原来那种写法不是线程安全的,重新写了一遍,求拍砖。

C/C++ code
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;};


[解决办法]
任何一种 non—const static 对象,不论它是local或者non-local,在多线程环境中等待“某事发生”都会有麻烦···
[解决办法]
static CAssist sm_assist;
这个对象定义成全局的不就可以了吗?
这样的话,在进程刚启动的时候就会将这个对象初始化,就可以避免多线程的问题了。
[解决办法]
唉,一个单间模式被你们写成这样子。。。。服了你了。。。
去网上找点材料看看吧。模式编程的文章太多了。理论上搞清楚先再下手不迟。
另外注意你类设计的编码规范,你的CLASS复合类设计的工程规范要求么???
[解决办法]
下面是一个多线程的单例模式代码,大家看看,不过要用到boost库,没有boost库不能通过编译的:
C/C++ code
#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技术更加好
[解决办法]

探讨

哪位大牛能给段线程安全的单件模式的标准代码?
哪位大牛能给段线程安全的单件模式的标准代码?
哪位大牛能给段线程安全的单件模式的标准代码?
哪位大牛能给段线程安全的单件模式的标准代码?
哪位大牛能给段线程安全的单件模式的标准代码?
哪位大牛能给段线程安全的单件模式的标准代码?
哪位大牛能给段线程安全的单件模式的标准代码?
哪位大牛能给段线程安全的单件模式的标准代码?
哪位大牛能给段……

热点排行