单身人士模板设计问题

时间:2011-10-20 08:50:06

标签: c++ design-patterns singleton

我目前正在使用以下简单的单例类:

template<class T>
class singleton
    : boost::noncopyable
{
public:
    static T& get_instance()
        {
            assert(sm_instance != nullptr);
            return *static_cast<T*>(sm_instance);
        }

protected:
    singleton()
        {
            assert(sm_instance == nullptr);
            sm_instance = this;
        }
    virtual ~singleton()
        {
            assert(sm_instance != nullptr);
            sm_instance = nullptr;
        }

private:
    static singleton<T>* sm_instance;
};

template<class T> singleton<T>* singleton<T>::sm_instance = nullptr;


class example_one
    : public singleton<example_one>
{
    static example_one instance;
};

example_one example_one::instance;


class example_two
    : singleton<example_two>
{
    static example_two instance;
};

example_two example_two::instance;


// Usage:
example_one& x = example_one::get_instance();
example_two& y = example_two::get_instance();   // not accessible because 'example_two' uses 'private' to inherit from 'singleton<T>'

但是,我想调整一些事情。我不喜欢get_instance()继承到派生类。

我想做这样的事情(非工作代码):

template<class T>
T& get_singleton();

template<class T>
class singleton
{
    friend T& get_singleton()
        {
            assert(sm_instance != nullptr);
            return *static_cast<T*>(sm_instance);
        }   
}

// Usage:
example_two& x = get_singleton<example_two>();

2 个答案:

答案 0 :(得分:0)

如果您打算使用模板函数,为什么还要打扰基类:

template<typename T>
T& getInstance()
{
     static T  instance;
     return instance;
}

class example_one: boost::noncopyable
{
       example_one() {}  // Note private construtor
       friend example_one& getInstance<example_one>();
};

class example_two: boost::noncopyable
{
       example_two() {}
       friend example_two& getInstance<example_two>();
};

答案 1 :(得分:0)

Andrei Alexandrescu推广的解决方案使用了一种不同的技术,与此相比具有多种优势(其中一种是你想要的调整)。它可以在http://loki-lib.cvs.sourceforge.net/loki-lib/loki/include/loki/Singleton.h?view=markup获得,但你可能想要下载整个库(loki),或者如果你不需要额外的东西就清理一下。然后界面变为:

typedef Loki::SingletonHolder< SomeType > SomeTypeSingleton;
SomeTypeSingleton::Instance(); // Access the single instance