一个静态对象,而析构函数是范围感知的

时间:2014-03-30 13:23:31

标签: c++

这是我问题的一个简单形式。我在函数A中有一个静态对象f,我们知道在完成不退出f的程序后将调用该对象的析构函数。

但是这个对象需要知道它的作用域何时退出然后它将执行它的destuctor。为了使它自动化,我编写了一个辅助类AutoScope,它与该对象的范围相同。

struct A {
    A() {
        cout << "Hi" << endl;
    }

    ~A() {
        cout << "Bye" << endl;
    }
};

template <typename T>
struct AutoScope {
    T &t;
public:
    AutoScope(T &t) : t(t) {
    }
    ~AutoScope() {
        t.~T();
    }
};

void f() {
    static A a;
    AutoScope<A> tmp(a);
}

int main() {
    f();
    f();
    f();

    cout << "end!" << endl;
}

输出

Hi
Bye
Bye
Bye
end!
Bye

好的,我想知道有没有办法将它与类结合起来才能拥有这个功能。一个静态的类,同时它的析构函数与非静态对象一样调用。

2 个答案:

答案 0 :(得分:1)

您尝试实现的行为类似于std::lock_guardstd::mutex的行为。

当特定范围结束时,您希望在对象上调用特定函数(在本例中为析构函数)。

如果没有附加类,我不相信这是可能的,因为静态对象的范围是全局的,并且在c++中没有机制,据我所知告诉检测较小范围的结束而没有使用一个作用于该局部范围的辅助对象。

我建议将~A()改为其他函数,因为函数的用途并不真正与“破坏”本身相关联,因为你实际上并没有破坏对象。

答案 1 :(得分:1)

如果您只想保证在退出函数时调用某些代码,那么最好的办法就是将它绑定到local-object析构函数中。但是,不需要该对象来销毁静态对象。而不是调用t.~T(),只需调用一些清理成员函数,例如t.cleanup()

如果您正在使用C ++ 11(大多数编译器现在支持它),您可以使用lambdas为此构建一个更通用的类:

struct AutoScope {
    std::function<void()> f;
    AutoScope(std::function<void()> const &f) : f(f) { }
    ~AutoScope() { f(); }
};

void f() {
    static A a;
    AutoScope tmp([&]{
        // Do cleanup here.
    });
}