我已经实现了一个模板化的单例界面,这里只是它的一小部分:
template<class T>
class SingletonObject {
private:
static boost::shared_ptr<T> instance_ptr;
static boost::mutex thread_safety_mutex;
SingletonObject() {}
~SingletonObject() {}
SingletonObject(const SingletonObject&) {}
void operator=(const SingletonObject&) {}
public:
static boost::shared_ptr<T> getInstance_ptr() {
using namespace boost::details::pool;
guard<boost::mutex> thread_safety_guard(thread_safety_mutex);
if (!instance_ptr) {
instance_ptr.reset(new T());
atexit(singletonMemoryHandler<T>);
}
return instance_ptr;
}
...
};
...
template<class T>
void singletonMemoryHandler() {
SingletonObject<T>::destroyInstance();
}
所以前面的代码段显示了getInterface_ptr()
的实现。其中的问题是我只能使用无参数创建SingletonObject
。
现在,我正在寻找一种传递不同类型参数的方法。
例如,单例化对象可以这样构造:
SingletonizableObj1(T1 a1, T2 a2, T3 a3);
SingletonizableObj2(T1 a1, T4 a2, T5 a3, T6 a4);
...
这样new T()
就可以成为new T(T1 a1 ... Tn n)
(也许这个参数列表可以在getInstance_ptr(T1 a1 ... Tn n)
内传递。
有没有一种简单的方法来实现这一目标?
EDIT1: 这可能是一个具体的例子:
Probe(std::queue<Packet>& recv_pkts, std::queue<Packet>& send_pkts, Sniffer& sniffer);
这个是构造一个带有三个引用参数的Probe
对象。我想解决这个问题的一种方法是,可以为每个单独的对象声明一个init
函数,因此SingletonObject
Probe
(没有参数结构中的参数)可以是:
...
// declarations
boost::shared_ptr<Probe> p(SingletonObject<Probe>::getInstance_ptr());
p->init(recv_pkts, send_pkts, sniffer);
...
但我还没有测试过它。
答案 0 :(得分:0)
template<class T> T& getSingleton() {static T r; return r;}
这就是你需要的所有单例框架。只需将所有ctors设为私有,并friend
进行正确的模板实例化。
现在,如果你想调用非默认ctors,对于其中任何一个,只需专门化它:
template<> Mega& getSingleton<Mega>() {static Mega r(1,2,3,4,5); return r;}
编译器将在首次使用时以线程安全的方式完成初始化。
如果您想使用std::shared_ptr
,那很容易。
如果你可以在最后销毁它,按照创建的顺序,使用非拥有的共享指针,如下所示:
template<class T> std::shared_ptr<T> getSharedSingleton()
{ return {std::shared_ptr<T>(), &getSingleton());
附注:您可能需要添加T* = 0
- 段以与旧编译器兼容。
答案 1 :(得分:0)
这是我找到的最佳方式:
static boost::shared_ptr<T> getInstance_ptr() {
...
if (!instance_ptr)
instance_ptr.reset(new T());
return instance_ptr;
}
template<class T1> static boost::shared_ptr<T> getInstance_ptr(T1& a1) {
...
if (!instance_ptr)
instance_ptr.reset(new T(a1));
return instance_ptr;
}
template<class T1, class T2> static boost::shared_ptr<T> getInstance_ptr(
T1& a1, T2& a2) {
...
if (!instance_ptr)
instance_ptr.reset(new T(a1, a2));
return instance_ptr;
}
template<class T1, class T2, class T3> static boost::shared_ptr<T> getInstance_ptr(
T1& a1, T2& a2, T3& a3) {
...
if (!instance_ptr)
instance_ptr.reset(new T(a1, a2, a3));
return instance_ptr;
}
...
我无法找到更好的解决方案来实现我的目标。使用之前的示例代码,对于不同数量的形式参数,它会显示geInstance_ptr
的大量重载。