RAII resource handling
Asked Answered
D

2

7

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?

Dysart answered 9/1, 2013 at 2:22 Comment(3)
Why are you not using std::auto_ptr (or std::unique_ptr if you are doing c++11)?Kidwell
Magic of compiler :) en.wikipedia.org/wiki/Destructor_(computer_programming)Casia
Doesn't RAII class need copy constructor and assignment operator?Shanan
C
6

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: }
Corpulent answered 14/10, 2013 at 6:29 Comment(0)
C
4

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!
Coppery answered 9/1, 2013 at 2:25 Comment(9)
I have a feeling this isn't helpful for him. How does it "automatically generate" the code?Rayner
@Pubby: How does a compiler do anything?Coppery
Just post where the destructors get added and a brief overview of the deterministic algorithm used or something.Rayner
@Pubby: But the OP already knows where the destructors get called!Coppery
@RamizHassan: Then please update your question to explain precisely what you're interested in ;)Coppery
@OliCharlesworth: I have a destructor in my class ~RAII() {delete p_;}, which i want to know how it get called while going out of scope? Why do i need to have a destructor if compiler generates the code for me anyway (as you said)?Dysart
@RamizHassan: Those are two separate questions. The first, I've already answered. For the second, you define a destructor if you want custom behaviour to occur when an object is destroyed.Coppery
@OliCharlesworth: yep I got it... Needed some time to think it out :). thanks I really appreciate your help.Dysart
@RamizHassan: You need a destructor because even though the compiler knows when to destroy your object, it doesn't necessarily know how.Delve

© 2022 - 2024 — McMap. All rights reserved.