多类型参数的变量函数

时间:2014-09-24 08:35:54

标签: c++ boost singleton variadic-functions

我已经实现了一个模板化的单例界面,这里只是它的一小部分:

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);
 ...

但我还没有测试过它。

2 个答案:

答案 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大量重载