首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C++11作用域出口保护,一个好主意?

C++11作用域出口保护,一个好主意?
EN

Stack Overflow用户
提问于 2010-09-09 00:24:41
回答 11查看 26.6K关注 0票数 25

我已经为C++11编写了一个小的实用程序类,我将其用作作用域保护,以便更容易地处理异常、安全和类似的事情。

看起来有点像黑客。但令我惊讶的是,我没有在其他使用C++11特性的地方看到它。我认为boost对C++98也有类似的东西。

但这是个好主意吗?或者是我遗漏了一些潜在的问题?boost或类似产品中是否已经有类似的解决方案(具有C++11功能)?

代码语言:javascript
运行
复制
    namespace detail 
    {
        template<typename T>
        class scope_exit : boost::noncopyable
        {
        public:         
            explicit scope_exit(T&& exitScope) : exitScope_(std::forward<T>(exitScope)){}
            ~scope_exit(){try{exitScope_();}catch(...){}}
        private:
            T exitScope_;
        };          

        template <typename T>
        scope_exit<T> create_scope_exit(T&& exitScope)
        {
            return scope_exit<T>(std::forward<T>(exitScope));
        }
    }


#define _UTILITY_EXIT_SCOPE_LINENAME_CAT(name, line) name##line
#define _UTILITY_EXIT_SCOPE_LINENAME(name, line) _UTILITY_EXIT_SCOPE_LINENAME_CAT(name, line)
#define UTILITY_SCOPE_EXIT(f) const auto& _UTILITY_EXIT_SCOPE_LINENAME(EXIT, __LINE__) = ::detail::create_scope_exit(f)

它使用了类似这样的东西。

代码语言:javascript
运行
复制
int main () 
{
  ofstream myfile;
  myfile.open ("example.txt");
  UTILITY_SCOPE_EXIT([&]{myfile.close();}); // Make sure to close file even in case of exception
  myfile << "Writing this to a file.\n"; // Imagine this could throw
  return 0;
}
EN

回答 11

Stack Overflow用户

回答已采纳

发布于 2010-09-09 00:31:39

但这是个好主意吗?

好的。一个相关的主题是RAII paradigm

或者是否有我遗漏的潜在问题?

你不需要处理异常。

boost或类似产品中是否已经有类似的解决方案(具有C++0x功能)?

Alexandrescu很早以前就提出了ScopeGuard。Boost和std::tr1都有一个叫做scoped_ptrshared_ptr的东西(有一个自定义的deleter),它可以让你实现这一点。

票数 21
EN

Stack Overflow用户

发布于 2010-09-09 01:38:03

需要指出的是,这里有Boost ScopeExit

票数 19
EN

Stack Overflow用户

发布于 2010-10-01 23:08:21

作用域保护绝对是个好主意。我认为作用域保护的概念是异常安全的有力工具。如果您可以使用C++0x语法创建一个更安全、更干净的Boost ScopeExit版本,我认为这将非常值得您花时间。

与Alexandrescu的ScopeGuard和Boost的ScopeExit类似,D programming language对这类事情有直接的语法。D编程团队认为作用域保护是一个足够好的想法,他们将其添加为directly to the language (即它不是在库中实现的)。

举例说明。

代码语言:javascript
运行
复制
void foo( bool fail )
{
   scope(exit)
   {
      writeln("I'm always printed");
   }

   scope(success) writeln("The function exited normally");

   scope(error)
      writeln("The function exited with an exception.");

   if( fail )
      throw new Exception("Die Die Die!");
}

基于范围的守卫并不是什么新鲜事。它的功能可以很容易地通过类析构函数(RAII和所有这些)来复制。它也可以在C#或Java中替换为try/finally。见鬼,即使是pthread也提供了一个基本的作用域保护,称为pthread_cleanup_push

作用域保护之所以如此强大,是因为函数中有多个scope(*)语句。它的伸缩性非常好,而try/finally需要超人的能力才能管理超过两个的任何东西。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3669833

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档