用于深层继承的C ++模板单例基类

时间:2012-10-16 21:16:49

标签: c++ templates singleton

所以我有一个简单的单例模板基类(为了问题目的而缩小):

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

现在我想要一个“基类是单身人士”:

class Base : public Singleton<Base> {
public:
    void print() { std::cout << &instance() << std::endl; }
}

我现在想要的是从这个基类派生子类,这是他们自己的单身人士:

class A : public Base {
    // ...
}

class B : public Base {
    // ...
}

当然,如果我这样做

A::instance().print();
B::instance().print();

我在两种情况下都得到相同的地址。有没有办法实现这个目标?

如果你想知道为什么:我想编写一个由ResourceManager类继承的ImageManager基类,一个类'AudioManager'等等。我想要他们不是实际共享同一个实例,但每个经理只有一个实例......

3 个答案:

答案 0 :(得分:5)

您必须将Base设为模板并将其传递给Singleton,然后如果您希望实现此目的,则从Base<A>继承。或者,如果您希望Base为Singleton 并且 A / B为Singleton,那么除{{1}之外,他们还必须继承Singleton<A>Singleton<B> }}

亲爱的领主,男人,单身人士对你和你的孩子们的诅咒已有一百代了。你为什么要这样做?

答案 1 :(得分:1)

我的建议是将Base设为非单例类,然后创建实例化Base类的A类和B类单例。这为您提供了灵活性,并遵循面向对象的原则,即有利于组合而不是继承http://www.artima.com/lejava/articles/designprinciples4.html

由于Singleton上需要静态成员,因此无法直接从Singleton类继承。在这种情况下,构图将更好地为您服务,而且大多数其他人也是如此。

答案 2 :(得分:1)

当基类必须从其子类中获取某些内容时,我看到的最佳解决方案是使用Child作为Base的参数,如下所示:

template< bool val, class TrueT, class FlaseT >
struct If {
    typedef TrueT type;
};
template< class TrueT, class FalseT >
struct If< false, TrueT, FalseT > {
    typedef FalseT type;
};
template< class DerivedT = void >
class Base {
public:
    typedef typename If<std::is_same<DerivedT, void>::value,
        Base<DerivedT>, DerivedT>::type this_type;
    static this_type& instance() {
        this_type me;
        return me;
    }

public:
    void test() {}
};
class A : public Base<A> {
public:
    void print() {}
};
class B : public Base<B> {
public:
    void print() {}
};
Base<>::instance().test();
B::instance().print();
A::instance().print();