RAII资源处理

时间:2013-01-09 02:22:19

标签: c++ destructor raii

我有一个RAII课程:


 template<typename T>
    class RAII
    {
    public:
    explicit RAII( T* p = 0 ): p_(p){}

    ~RAII() {delete p_;}

    T& operator*() const { return p_;} 
    T* operator‐>() const{ return p_;}
    };

{

RAII<std::vector<int>> r(new std::vector<int>());
std::cout<<r­‐>size()<<std::endl;

} // The std::vector<int> is automatically deallocated

我知道当我用完范围时,我的析构函数将被调用。 ~RAII() {delete P_};

我的问题是:

它如何调用我的析构函数?

2 个答案:

答案 0 :(得分:6)

当抛出异常并且控制从try块传递到处理程序时,C ++运行时调用自try块开始以来构造的所有自动对象的析构函数。此过程称为堆栈展开。自动对象按其构造的相反顺序销毁。 (自动对象是已声明为auto或register,或未声明为static或extern的本地对象。只要程序退出声明x的块,就会删除自动对象。)

如果在构造由子对象或数组元素组成的对象期间抛出异常,则只会在抛出异常之前为成功构造的子对象或数组元素调用析构函数。仅当成功构造对象时,才会调用本地静态对象的析构函数。

如果在堆栈展开期间析构函数抛出异常并且未处理该异常,则调用terminate()函数。

示例:请参阅下面的反汇编。你会看到析构函数已被推入堆栈。

class Test
{
public:
    Test()

    {
        std::cout<<"C'tor\n";
    }
    ~Test()
    {
        std::cout<<"D'tor\n";
    }
}
 int main()//_TCHAR* argv[])
{
Test();
}
00DD9C30 55                   push        ebp  
00DD9C31 8B EC                mov         ebp,esp  
00DD9C33 81 EC CC 00 00 00    sub         esp,0CCh  
00DD9C39 53                   push        ebx  
00DD9C3A 56                   push        esi  
00DD9C3B 57                   push        edi  
00DD9C3C 8D BD 34 FF FF FF    lea         edi,[ebp-0CCh]  
00DD9C42 B9 33 00 00 00       mov         ecx,33h  
00DD9C47 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
00DD9C4C F3 AB                rep stos    dword ptr es:[edi]  
    23: 
    24:     Test();
00DD9C4E 8D 8D 3B FF FF FF    lea         ecx,[ebp-0C5h]  
00DD9C54 E8 67 7C FF FF       call        Test::Test (0DD18C0h)  
00DD9C59 8D 8D 3B FF FF FF    lea         ecx,[ebp-0C5h]  
00DD9C5F E8 03 76 FF FF       call        Test::~Test (0DD1267h)
    25: }

答案 1 :(得分:4)

编译器自动生成代码以调用局部变量的析构函数。 *

<小时/> *从技术上讲,它们被称为“具有自动存储持续时间的对象”。应该清楚原因!