Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RAII resource handling

I have a RAII class:


 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

I know when I run out of scope my destructor will be called. ~RAII() {delete P_};

My question is:

How does it call my destructor?

like image 974
RamHS Avatar asked Jan 09 '13 02:01

RamHS


2 Answers

When an exception is thrown and control passes from a try block to a handler, the C++ run time calls destructors for all automatic objects constructed since the beginning of the try block. This process is called stack unwinding. The automatic objects are destroyed in reverse order of their construction. (Automatic objects are local objects that have been declared auto or register, or not declared static or extern. An automatic object x is deleted whenever the program exits the block in which x is declared.)

If an exception is thrown during construction of an object consisting of subobjects or array elements, destructors are only called for those subobjects or array elements successfully constructed before the exception was thrown. A destructor for a local static object will only be called if the object was successfully constructed.

If during stack unwinding a destructor throws an exception and that exception is not handled, the terminate() function is called.

Example : See disassembly below. You will see destructor is already pushed on stack.

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: }
like image 100
Satbir Avatar answered Oct 07 '22 10:10

Satbir


The compiler automatically generates code to call the destructors of local variables.*


* Technically, they're known as "objects with automatic storage duration". It should be clear why!
like image 36
Oliver Charlesworth Avatar answered Oct 07 '22 09:10

Oliver Charlesworth