如何继承神奇的静态单例?

问题描述 投票:0回答:1

我想从派生中的神奇静态单例继承:

#include <iostream>

int main();

class SingletonBase{
protected:
    int i=0;
    SingletonBase(int){}
    //
    friend int main();
    static void show(){
        static SingletonBase s(2); // this is sometimes referred to as the "magic static singleton pattern"
        s.i++;
        std::cout << "SingletonBase::i="<<s.i<<"\n";
    }
};

class Singleton: public SingletonBase{
private:
    Singleton(int):SingletonBase(int{}){}
    int j=0; // unfortunately, Singleton has data, too.
public:
    static void show(){
        static Singleton s(3);
        s.i++;
        s.j++;
        std::cout << "Singleton::SingletonBase::i="<<s.i<<". Singleton::j="<<s.j<<"\n";
    }
    //
};

int main() {
    Singleton::show();
    Singleton::show();
    Singleton::show();
    Singleton::show();
    SingletonBase::show();
    SingletonBase::show();
    SingletonBase::show();
    Singleton::show();
    Singleton::show();
    Singleton::show();
    Singleton::show();
}

输出为:

Singleton::SingletonBase::i=1. Singleton::j=1
Singleton::SingletonBase::i=2. Singleton::j=2
Singleton::SingletonBase::i=3. Singleton::j=3
Singleton::SingletonBase::i=4. Singleton::j=4
SingletonBase::i=1
SingletonBase::i=2
SingletonBase::i=3
Singleton::SingletonBase::i=5. Singleton::j=5
Singleton::SingletonBase::i=6. Singleton::j=6
Singleton::SingletonBase::i=7. Singleton::j=7
Singleton::SingletonBase::i=8. Singleton::j=8

但我期望(和需要)的是每条输出线中的

i
增加
1
。也就是说,theSingleton(应该只有一个)应继承theSingletonBase。

这怎么办?

备注

我无法与 main 解除好友关系。

应用程序上下文是我有两种不同的类型

template<typename T>ElementA
template<typename T>ElementB
,具有很多共同的功能。所以我从
template<typename T>ElementBase
继承了两者。两者都分别将东西放在
StackA<T>
StackB<T>
上,依次共享很多功能。所以我从
StackBase<T>
继承了这两个堆栈。在上面的例子中,
main
是调用
ElementBase
SingletonBase
SingletonBase
又是
StackBase
,因为它是
Singleton
的基础,它模拟
StackA / StackB

main
解除好友关系意味着
ElementBase<T>
无法推进
StackBase<T>
,这意味着我必须冗余地实现A和B的所有内容。

c++11 singleton static-methods
1个回答
0
投票

警告:丑陋。

#include <iostream>

int main();

class SingletonBase{
private:
    int i=0;
    SingletonBase(int){}
    //
    friend int main();
    friend class Singleton;
protected:
    static SingletonBase& Instance(){
        static SingletonBase s(int{});
        return s;
    }
    static void show(){
        std::cout << "SingletonBase::i="<< Instance().i++ << "\n";
    }
};

class Singleton{
private:
    Singleton(int){}
    SingletonBase* b;
public:
    //
    static Singleton& Instance(){
        static Singleton s(int{});
        s.b = &SingletonBase::Instance();
        return s;
    }
    static void show(){
        std::cout << "Singleton.SingletonBase->i="<< Instance().b->i++ << "\n";
    }
    //
};

int main() {
    SingletonBase::Instance().show();
    SingletonBase::Instance().show();
    Singleton::Instance().show();
    SingletonBase::Instance().show();
    Singleton::Instance().show();
    SingletonBase::Instance().show();
}

因此,我们的想法是通过使用指向基类的指针而不是继承它来组合 Singleton 及其基类的静态状态。由于两个单例与外部的接口都是通过

Instance()
函数传递的,因此剩下的唯一风险是单例实现中的内存泄漏(例如覆盖
b
)。

© www.soinside.com 2019 - 2024. All rights reserved.