raii
Ellery Newcomer
ellery-newcomer at utulsa.edu
Sun Feb 28 12:16:32 PST 2010
Hello
The impetus:
> I agree, except I more and more think that scope classes were a mistake. Structs with destructors are a much better solution, and wrapping a class inside a struct would give it RAII semantics.
The problem:
In designing a library (or rather touching up someone else's library), I
have a class (interface?) Foo, and it has a method close (actually
several methods). Almost invariably (although conceivably not always),
usage involves manipulating Foo, and then remembering to call close.
That last part is obnoxious.
One obtains a Foo from function foo.
What I'd like is for the result of foo to have RAII semantics by
default, with the possibility of nixing it if the user actually cares.
I want to take the burden of remembering that stupid close off the user.
For example:
void bar(){
auto a = foo();
a.doStuff();
}
has an implicit call to close after doStuff.
The impetus suggests I can do this by wrapping Foo inside a struct, but
I'm not so sure how well this would work out. Also note that close can
fail in a number of ways relating to file io.
So I wrote up a simple prototype.
Thoughts?
import std.stdio;
class Foo{
int k;
this(int i){
writefln("bin %d",k);
k = i;
}
void doStuff(){
writefln("do stuff %d",k);
}
void close(){
writefln("close %d",k);
}
}
struct RAII(T){
T b;
bool extracted = false;
alias b this;
this (T i){
assert(i !is null);
writeln("in");
b = i;
}
~this(){
writeln("~this");
if(!extracted) b.close();
}
T extract(){
assert(!extracted);
T t = b;
b = null;
extracted = true;
return t;
}
}
RAII!(Foo) foo(int i){
return RAII!(Foo)(new Foo(i));
}
void main(){
auto a = foo(1);
auto b = foo(2).extract();
a.doStuff();
b.doStuff();
}
More information about the Digitalmars-d-learn
mailing list