0

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

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”等继承。我希望它们实际上不共享同一个实例,但仍然只有每个经理一个实例...

4

3 回答 3

6

您必须将 Base 设为模板并将其传递给,然后如果您希望实现此目的Singleton,则继承自。Base<A>或者,如果您希望 Base 成为 Singleton并且A/B 成为 Singleton,那么它们将必须继承自Singleton<A>Singleton<B>除了Base.

但是亲爱的上帝,伙计,单身对你和你的孩子来说是一百代人的诅咒。你为什么要这样对自己?

于 2012-10-16T21:19:26.040 回答
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();
于 2012-10-16T21:27:38.520 回答
1

我的建议是让 Base 成为一个非单例类,然后让 Class A 和 Class B 单例实例化 Base 类。这为您提供了灵活性并遵循了优先组合而不是继承的面向对象原则http://www.artima.com/lejava/articles/designprinciples4.html

由于 Singleton 需要静态成员,您不能直接从 Singleton 类继承。在这种情况下,作曲会更好地为您服务,大多数其他情况也是如此。

于 2012-10-16T21:27:12.393 回答