我想从派生中的神奇静态单例继承:
#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的所有内容。
警告:丑陋。
#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
)。