繁体   English   中英

C ++ Singleton模板类继承

[英]C++ Singleton template class inheritance

我有一个抽象的Singleton类。 我的目标是任何子类只需要实现init()函数和NOTHING ELSE。 这是我做的:

template <typename T>
class Singleton
{
    public: 

        Singleton()
        {
            init();
        }

        static T& instance()
        {
            static T instance;
            return instance;
        }

    protected:
        virtual void init() = 0;   
};

class SubSingleton : public Singleton<SubSingleton>
{
    protected: 
        void init()
        {
            cout << "Init SubSingleton" << endl;
        }
};

这将无法编译,因为init()受到保护,无法从公共静态函数调用。 这个问题有两个解决方案。 首先我们可以将init()函数设为public,但我不想公开公开这个函数。 所以这只留下第二个解决方案,更改子类如下:

class SubSingleton : public Singleton<SubSingleton>
{
    friend class Singleton<SubSingleton>;

    protected:

        void init()
        {
            cout << "Init SubSingleton" << endl;
        }
};

这很好用,但我不想要友元声明,因为其他程序员可能会扩展我的代码,可能不知道应该添加它。

没有朋友声明,还有其他方法可以实现吗? 也许Andrei Alexandrescu的一切?

编辑:现在在构造函数中调用init函数而不是instance()函数。

EDIT2:由于技术原因和兼容性,我需要一个init()函数,不能只在构造函数中进行初始化。

用于转换的解决方案可行,但如果我从构造函数中调用init(),则转换不再起作用。 有什么建议?

问题是您不打算使用虚拟功能。 我现在没有多态行动了。 为什么? 因为你在直接派生对象上调用init()。 使用init()函数是虚拟的是在基类引用或基类指针上调用init(),如下所示。 然后调用从基类范围发生,因为instance()方法是基类方法,从中调用受保护的方法是完全正常的。

    static T& instance()
    {
        static T myInstance;
        Singleton<T>& t = myInstance;  // Just define a dummy reference here.
        t.init();
        return myInstance;
    }

你根本不需要这个init()的东西。 这只会产生问题。

template <typename T>
class Singleton
{
    public: 
        static T& instance()
        {
            static T instance;
            return instance;
        }
};

class SubSingleton : public Singleton<SubSingleton>
{
    public: 
        SubSingleton()
        {
            cout << "Init SubSingleton" << endl;
        }
};

这样你不仅可以删除不必要的东西 - 而且每次有人调用instanse()时你也会阻止调用init()......

看来你混合了两种类型的polimorphysms:

1)如果你想“静态地”调用SubSingleton::init() ,即使用CRTP,你不需要在基类中定义它 - 但是你真的必须让它可以被基类访问。

2)但是如果将init()定义为virtual,则使用动态polimorphism,并且不需要使init() public:

static T& instance() 
{ 
  static T instance; 
  static_cast<Singleton<T> &>(instance).init(); 
  return instance; 
} 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM