单例模板设计问题

发布于 2024-12-11 03:07:49 字数 1571 浏览 0 评论 0原文

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

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>();

I'm currently using the following simple singleton class:

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>'

However, I would like to tweak some things. I don't like that get_instance() is inherited to the derivative class.

I would like to do something like this (non-working code):

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>();

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

他是夢罘是命 2024-12-18 03:07:49

如果您要使用模板函数,为什么还要费心使用基类:

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>();
};

If you are going to use a template function why bother with the base class:

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>();
};
北城孤痞 2024-12-18 03:07:49

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

The solution popularized by Andrei Alexandrescu uses a different technique, which has several benefits compared to this one ( one of which is the tweak you want to make ). It's available at http://loki-lib.cvs.sourceforge.net/loki-lib/loki/include/loki/Singleton.h?view=markup , but you probably want to download the whole library ( loki ), or clean it up a bit if you don't need the extras. The interface then becomes:

typedef Loki::SingletonHolder< SomeType > SomeTypeSingleton;
SomeTypeSingleton::Instance(); // Access the single instance
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文