1

我想创建一个守卫,它在构造时锁定函数并在销毁时解锁它,例如使用falseand调用函数true

class A {
void enable( bool flag );
};

在另一种方法中,我想使用:

A::anotherMethod( ... ) {
  block_guard(A::enable); // now A::enable(false)
  // some operation
} // now A::enable(true)

我的想法:

使用模板

template < class T >
class block_guard {
  T t_;
public:
  block_guard( T& t ) : t_(t) {
    t_(false);
  }
  ~block_guard() {
    t_(true);
  }
};

问题是,如何实例化模板?也许与boost::bind

使用 boost::function

class block_guard {
  typedef boost::function< void (bool) > T;
  T t_;
public:
  block_guard( T& t ) : t_(t) {
    t_(false);
  }
  ~block_guard() {
    t_(true);
  }
};

这工作正常,但调用似乎很复杂

block_guard bg(boost::function< void (bool) >(boost::bind(&A::enable, pointer-to-A, _1));

有任何想法吗?也许还有另一种更简单的方法?

4

2 回答 2

2

首先,意识到成员函数并不是你所需要的;您还需要对象来调用它。在 C++ 中,函数中创建的对象无法隐式捕获当前this指针。

我假设您没有可用的 C++11。如果这样做,使用带有 lambda 表达式的第二个解决方案是最简单的。

现在,如果您不关心 boost::function 对性能的轻微影响(并且您不应该),那么第二种解决方案很好,但我会稍微修改它以通过将绑定拉入以使其更方便使用构造函数。

class block_guard {
  typedef boost::function< void (bool) > block_fn;
  block_fn block_fn_;
public:
  // For non-member functions and function objects:
  template <typename Fn>
  block_guard(Fn fn) : block_fn_(fn) {
    block_fn_(false);
  }
  // For member functions:
  template <typename T, typename Ret>
  block_guard(T* obj, Ret (T::*fn)(bool)) : block_fn_(boost::bind(fn, obj, _1)) {
    block_fn_(false);
  }
  ~block_guard() {
    block_fn_(true);
  }
};

用法:

block_guard guard(this, &A::enable);

我在这里使用了一个 Ret 参数,因为没有理由不允许函数返回一些东西——返回值将被忽略。

如果你不想要 boost::function,这个东西会变得不那么容易使用,因为你必须模板化块保护。然后,专门为成员函数制作一个 block_guard 就变得很有用了。你也失去了使用非空函数的能力。

template <typename T>
class block_guard {
  typedef void (T::*block_fn)(bool);
  T* obj_;
  block_fn block_fn_;
public:
  block_guard(T* obj, block_fn fn) : obj_(obj), block_fn_(fn) {
    (obj_->*block_fn_)(false);
  }
  ~block_guard() {
    (obj_->*block_fn_)(true);
  }
};

用法:

block_guard<A> guard(this, &A::enable);
于 2013-06-13T10:35:39.177 回答
0

是的,有一个更简单的方法,忘记模板、通用的东西和任何不必要的东西,专注于任务。

您所需要的只是一个带有 ctor 和 dtor 的类。首先编写 dtor,它揭示了您需要工作的内容。然后编写 ctor,根据需要接受参数。最后删除不需要的函数(cctor,op=)。完毕。

不是通用的,但直截了当。

于 2013-06-13T10:46:55.887 回答