简体   繁体   English

如何创建类似于boost :: lock_guard的后卫

[英]how to create guard similar to boost::lock_guard

I want to create a guard, which locks a function on construction and unlocks it on destruction, eg calling the function with false and true . 我想创建一个防护,该防护在构造时锁定功能,在破坏时解锁功能,例如,使用falsetrue调用功能。

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

within another method, I want to use: 在另一种方法中,我想使用:

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

my ideas: 我的想法:

using template 使用模板

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

the question is, how to instantiate the template? 问题是,如何实例化模板? maybe with boost::bind ? 也许与boost::bind

using boost::function 使用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);
  }
};

this works fine, but the call seems to be very complicated with 这个工作正常,但是调用似乎非常复杂

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

any ideas? 有任何想法吗? maybe there is another, much simpler way? 也许还有另一种更简单的方法?

First, realize that the member function is not all you need; 首先,意识到成员函数并不是您所需要的; you also need the object to invoke it on. 您还需要对象来对其进行调用。 There is no way in C++ for an object created in a function to implicitly capture the current this pointer. 在C ++中,无法通过函数创建的对象隐式捕获当前的this指针。

I'm going to assume you don't have C++11 available. 我将假设您没有C ++ 11。 If you do, using your second solution with a lambda expression is easiest. 如果这样做,使用带有lambda表达式的第二个解决方案是最简单的。

Now, if you don't care about the slight performance hit of boost::function (and you shouldn't), the second solution is good, but I would modify it slightly to make it more convenient to use by pulling the bind into the constructor. 现在,如果您不关心boost :: function的轻微性能下降(并且您不应该这样做),第二种解决方案很好,但是我会对其进行一些修改,以通过将bind插入其中来使其更方便使用。构造函数。

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

Usage: 用法:

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

I use a Ret parameter here because there's no reason not to allow functions that return something - the return value will simply get ignored. 我在这里使用Ret参数是因为没有理由不允许函数返回某些东西-返回值将被忽略。

If you don't want boost::function, the thing will get less easy to use, because you have to template the block guard. 如果您不想使用boost :: function,那么事情将变得不那么容易使用,因为您必须模板化块防护。 It becomes useful to make a block_guard specifically for member functions then. 然后,专门为成员函数创建一个block_guard很有用。 You also lose the ability to use non-void functions. 您还将失去使用非无效函数的能力。

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

Usage: 用法:

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

Yes, there is a much simpler way, forget templates, generic thing and whatever not necessary and focus on the task. 是的,有一种简单得多的方法,忘记模板,通用的东西以及任何不必要的东西,而将精力集中在任务上。

All you need is a class with a ctor and a dtor. 您所需要的只是一门带有ctor和dtor的类。 Write the dtor first, it reveals what you will need to work. 首先编写dtor,它揭示了您需要进行的工作。 Then write the ctor, taking arguments as needed. 然后编写ctor,根据需要接受参数。 Lastly make the unwanted functions deleted (cctor, op=). 最后,删除不需要的功能(cctor,op =)。 Done. 完成。

Not generic, but straight to the point. 不是通用的,而是直截了当。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM