C ++中的ScopeGuard是什么? [英] What is ScopeGuard in C++?
问题描述
我觉得它是第三方编写的库中包含的C ++类。我尝试在Google上进行搜索,但发现一条帖子称使用它是一个好主意。但是,它无法准确描述其含义以及如何将其合并到代码中。谢谢。
I am under the impression that it is a C++ class contained in a library written by a third party. I tried searching on Google, and I found one post that said it was a good idea to use it. However, it failed to describe exactly what it is and how I can incorporate it into my code. Thanks.
推荐答案
ScopeGuard
was once a particular implementation of scope guards by Petru Marginean and Andrei Alexandrescu. The idea is to let the destructor of a guard object call a user specified cleanup action at the end of a scope (read: block), unless the scope guard is dismissed. Marginean came up with an ingenious idea of declaring a scope guard object for C++03, based on lifetime extension of a reference to const
.
今天"保镖”
Today “scope guard” is more the general idea.
范围警卫基于RAII(用于清理的自动析构函数调用),例如 for
循环基于跳转,但是通常不会调用 for
循环是基于跳转的代码,因为那样会丢失有关其内容的大部分信息,并且同样,通常不会将范围后卫称为RAII。 for
循环比跳转具有更高的抽象层次,并且是一个更专业的概念。范围警卫比RAII具有更高的抽象层次和更专业的概念。
Scope guards are based on RAII (automatic destructor calls used for cleanup), just as e.g. a for
loop is based on jumps, but one wouldn't ordinarly call a for
loop a jump-based piece of code, because that loses most of the information of what it is about, and likewise one does not ordinarily refer to scope guards as RAII. for
loops are at a higher level of abstraction, and are a more specialized concept, than jumps. Scope guards are at a higher level of abstraction, and are a more specialized concept, than RAII.
在C ++中可以通过 std :: function
轻松实现11个范围卫,并通过lambda表达式在每个位置提供清理操作。
In C++11 scope guards can be trivially implemented in terms of std::function
, with the cleanup action supplied in each place via a lambda expression.
示例:
#include <functional> // std::function
#include <utility> // std::move
namespace my {
using std::function;
using std::move;
class Non_copyable
{
private:
auto operator=( Non_copyable const& ) -> Non_copyable& = delete;
Non_copyable( Non_copyable const& ) = delete;
public:
auto operator=( Non_copyable&& ) -> Non_copyable& = default;
Non_copyable() = default;
Non_copyable( Non_copyable&& ) = default;
};
class Scope_guard
: public Non_copyable
{
private:
function<void()> cleanup_;
public:
friend
void dismiss( Scope_guard& g ) { g.cleanup_ = []{}; }
~Scope_guard() { cleanup_(); }
template< class Func >
Scope_guard( Func const& cleanup )
: cleanup_( cleanup )
{}
Scope_guard( Scope_guard&& other )
: cleanup_( move( other.cleanup_ ) )
{ dismiss( other ); }
};
} // namespace my
#include <iostream>
void foo() {}
auto main() -> int
{
using namespace std;
my::Scope_guard const final_action = []{ wclog << "Finished! (Exit from main.)\n"; };
wcout << "The answer is probably " << 6*7 << ".\n";
}
函数的作用
此处是为了避免模板化,以便可以这样声明 Scope_guard
实例并进行传递。另一种稍微复杂一些,用法受限制的方法,但可能稍微有点效率,那就是在函子类型上模板化一个类,并使用C ++ 11 auto
声明,以及由工厂函数创建的范围保护实例。这两种技术都是C ++ 11的简单方法,可以完成Marginean在C ++ 03的参考生存期扩展方面的工作。
The rôle of the function
here is to avoid templating so that Scope_guard
instances can be declared as such, and passed around. An alternative, slightly more complex and with slightly constrained usage, but possibly marginally more efficient, is to have a class templated on a functor type, and use C++11 auto
for declarations, with the scope guard instance created by a factory function. Both these techniques are simple C++11 ways to do what Marginean did with reference lifetime extension for C++03.
这篇关于C ++中的ScopeGuard是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!