派生自单例:基数和派生各一个对象

Deriving from singleton : one object each of base and derived?

本文关键字:派生 一个对象 单例      更新时间:2023-10-16

我有一个singleton class A,有virtual protected destructorprivate constructor。我公开从中衍生并创建了 B 类。

我可以创建两个对象,分别是基类和派生类吗?

如果我不能,还有其他方法可以共享相同的代码吗?

当我尝试它时,我收到编译时错误:

warning C4356: 'A::variable' : static data member cannot be initialized 
via derived class
B.cpp(4): error C2371: 'variable' : redefinition; different basic types

这完全取决于您的单例是如何实现的。 如果它有某种公共构造函数,那么您可能可以将其单例性扩展到B的派生实例。 如果它是某种工厂方法,那么可能不是。 它具有protected dtor的事实表明它是为用作基类而构建的。

不要与两个独立的习语混淆:

  • 继承是C++语言机制的一部分
  • 单一实例是一种实例化策略,在代码中定义

因此,您的问题的答案是"这取决于您如何实现实例化策略"。

如果我理解正确,您想要实现的是一个可重用的单例模式基类。可以使用模板基类和名为 CRTP 的模式来执行此操作。这个问题也提供了这种技术的简单解释。

具体来说,这意味着做这样的事情:

template<typename TDerived>
class Singleton {
public:
    static TDerived& instance() {
         static TDerived instance_;
         return instance_;
    }
protected:
    Singleton() {}
    virtual ~Singleton() {}
};
class ConcreteSingleton : public Singleton<ConcreteSingleton> {
public:
    ...
protected:
    ConcreteSingleton() {
         ...
    }
    virtual ~ConcreteSingleton() {
         ...
    }
};

此特定版本要求基类具有默认构造函数。其他更复杂的接口可以缓解这个问题。

总体而言,正如一些评论中所指出的,单例作为一种模式存在可伸缩性问题,尽管常量单例通常被认为更安全。

相关文章: