6

我正在研究资源管理类,并希望用户为“ReleaseResource”方法提供一个函子,作为资源管理器构造函数的一部分。从那里请求资源时,将提供函子作为我将返回的 shared_ptr 的删除器,以便在不再使用资源时调用适当的方法。

我遇到的问题是,这需要我将仿函数存储在我的班级中,我不完全确定如何做到这一点。通常在使用仿函数时,您可以像这样对函数进行模板化:

template<class MyFunctor> MyMethod(MyFunctor f) {
    f();
}

如果您打算在该函数的范围内使用仿函数,这很好,但是由于模板超出了函数的范围,我不确定您将如何指定适当类型的变量来存储仿函数以供以后使用.

谁能在这里指出我正确的方向?

4

3 回答 3

8
template<class MyFunctor> MyMethod(MyFunctor f) {
    boost::function<void()> g = f;
    g();
}

您传递给boost::function的类型是函数类型。例如,int(bool, char)是返回 int 并采用 bool 和 char 的函数的类型。也就是说,如果您想立即构造 shared_ptr,则不需要将仿函数存储在某处(boost::function需要new运算符,即使对于非常小的仿函数,它也会使用特殊技巧仅使用堆栈分配(小缓冲区优化)):

template<class MyFunctor> MyMethod(MyFunctor f) {
    boost::shared_ptr<T> ptr(new T, f);
}

boost::function 是tr1并将成为下一个官方 C++ 标准的一部分。例子:

struct Manager {
    template<typename Deleter>
    Manager(Deleter d) 
        :deleter(d) {

    }

    boost::shared_ptr<Resource> allocate() {
        ...
        return boost::shared_ptr<Resource>(resource, deleter);
    }

private:
    boost::function<void(Resource *)> deleter;
};
于 2009-01-23T20:25:06.227 回答
3

有两种方法,这两种方法都归结为模板类。

template <MyFunctor>
class MyClass
{
   MyFunctor   func;
  public:
    MyClass(MyFunctor f) :func(f)
    { }


    MyMethod() 
   {
       func();
   }
}

这需要你知道函子的类型。为了避免这种情况,我们可以使用工厂:

 template<MyFunctor>
 MyClass<MyFunctor>  MakeFunctorClass(MyFunctor f)
 {     
     return MyClass<MyFunctor>(f);       
 }

或者,由于很可能大部分函子签名都是相同的,只有一小部分发生变化,我们可以使用它:

template <MyType>
class MyClass
{
   typedef std::binary_function<MyType, MyType, bool>  MyFunctor;
   MyFunctor func;
  public:


    MyMethod(MyFunctor f) 
   {
       func = f;
       func();
   }
}

这使得使用更简单:

 bool AreEqual(int, int); 
 MyClass<int> myc;
 myc.MyMethod(AreEqual);

以更复杂的定义为代价(即,我不保证我给出的 binary_function typedef 会起作用)

于 2009-01-23T20:27:34.507 回答
0

不确定这是否有帮助,但请注意 boost::shared_ptr 具有构造函数覆盖,允许用户包含自定义取消分配(和自定义分配器,如果需要)。这可能足以满足您的需要(如果我正确阅读您的用例,它的设计考虑到了这一点)。

于 2009-01-23T20:04:50.713 回答