离开范围时调用函数

时间:2014-03-26 09:26:48

标签: c++ c++11 scope raii

离开示波器时自动调用函数的最佳解决方案是什么? 我当前的方法(见下文)works但我想应该有一些更通用的东西为此编写自定义类。

#include <iostream>
#include <functional>

using namespace std;

class DoInDtor
{
public:
    typedef function<void()> F;
    DoInDtor(F f) : f_(f) {};
    ~DoInDtor() { f_(); }
private:
    F f_;
};

void foo()
{
    DoInDtor byeSayerCustom([](){ cout << "bye\n"; });

    auto cond = true; // could of course also be false
    if ( cond )
        return;

    return;
}

int main()
{
    foo();
}

当然,有人可能会滥用std :: unique_ptr及其自定义删除器,但由于我并不真正在这里获取资源,因此在代码可读性方面对我来说听起来不太好。有什么建议吗?

2 个答案:

答案 0 :(得分:1)

以这种方式使用构造函数/析构函数是解决此排序问题的常用方法。我已经将它用于两个锁(构造函数锁定,析构函数释放它)和日志记录目的(构造函数在构造上打印一些东西,析构函数在破坏时打印,给出项目的一个很好的调用图 - 在后一种情况下,使用宏也可以获得__FILE____LINE__存储在对象中,因此我们可以看到构造函数的调用位置[对于析构函数来说几乎不可能这样做,但通常可以看到它构造函数并确定析构函数的调用位置])。

答案 1 :(得分:0)

Angew和Cassio用ScopeGuard指出了你正确的方向。使用std :: function可能会产生动态内存分配,并不是最有效的解决方案。基于ScopeGuard的实现通过编码函数对象的类型来调用ScopeGuard类本身作为模板参数来避免这种情况。使用辅助函数模板,您永远不必显式声明该类型,编译器会为您推断它(并且必须在lambda被用作函数对象的情况下调用)。

我最近写了两篇关于这个领域的文章,而不是重复这里的所有细节:

第一篇文章侧重于简单性,并从与原始问题类似的地方开始,包括一个激励性的例子。第二个步骤完成所有步骤,将其演变为高效且强大的实现,从而生成简洁,可读的代码。第二篇文章还解释了所提供的材料如何与Andrei与ScopeGuard的工作以及Cassio提到的scope_exit的C ++标准提案相关。