Recommended way to do RAII cleanly

Rory McGuire rmcguire at neonova.co.za
Mon Jul 12 00:27:11 PDT 2010


On Mon, 12 Jul 2010 08:25:32 +0200, Jonathan M Davis  
<jmdavisprog at gmail.com> wrote:

> Okay. There are cases where you want a constructor to do something when  
> the
> class/struct is created, and you want the destructor to do something  
> when the
> class/struct goes out of scope. A classic example would be an autolock  
> for a
> mutex. Another would be the hourglass in MFC - it's displayed when the  
> object is
> created and disappears when the object is destroyed (so all you have to  
> do is
> declare the object it at the beggining of the function and it  
> automatically is
> displayed and then disappears). This is classic RAII.
>
> Obviously, because classes are reference types with infinite lifetime  
> while
> structs are value types with their lifetime restricted to their scope,  
> structs
> would be the better choice for RAII. I have noticed a bit of a snag  
> however:
> structs can't have default constructors.
>
> After reading TDPL, I completely understand that structs can't have  
> default
> constructors due to how the init property works. However, the classic  
> case where
> you want to simply declare an object and have it do what it does through  
> RAII
> then falls apart. Ideally, you'd have something like this
>
> struct S
> {
>     this()
>     {
>         /* do something */
>     }
>
>     ~this()
>     {
>        /* undo what you did before or do whatever clean up is required  
> for it */
>     }
> }
>
> void main()
> {
>     auto s = S();
>    /* whatever the rest of main() does */
> }
>
>
> Thanks to the lack of default constructor, you can't do that. Therefore,  
> I see 2
> options:
>
> 1.  Create a nonsensical constructor that takes an argument of _some_  
> kind which
> is totally ignored.
>
> 2. Create a factory function to create the struct, and it does whatever  
> would
> have been in the default constructor.
>
>
> Out of those two options, the second seems the best, but it seems to me  
> that
> there have got to be more options than that. So, the question is what  
> would be
> the best option (be it one of those or another that I haven't though of)  
> to do
> RAII in the general case? What would be "best practice" for D when  
> dealing with
> structs intended for RAII without any arguments to their constructor  
> when you
> can't have a default constructor?
>
> - Jonathan M Davis

Do you know about the scope storage class, or about scope classes?

{
	scope tmp = new A();

	// use tmp;

	tmp destructor is called.
}

scope classes are similar:
http://www.digitalmars.com/d/2.0/class.html


More information about the Digitalmars-d-learn mailing list