views:

414

answers:

4

Is there any template available in boost for RAII. There are classes like scoped_ptr, shared_ptr which basically work on pointer. Can those classes be used for any other resources other than pointers. Is there any template which works with a general resources.

Take for example some resource which is acquired in the beginning of a scope and has to be somehow released at the end of scope. Both acquire and release take some steps. We could write a template which takes two(or maybe one object) functors which do this task. I havent thought it through how this can be achieved, i was just wondering are there any existing methods to do it

Edit: How about one in C++0x with support for lambda functions

+5  A: 

The most generic approach is the ScopeGuard one (basic idea in this ddj article, implemented e.g. with convenience macros in Boost.ScopeExit), and lets you execute functions or clean up resources at scope exit.

But to be honest, i don't see why you'd want that. While i understand that its a bit annoying to write a class every time for a one-step-aquire and one-step-release pattern, you are talking about multi-step-aquire and -release.
If its taken multiple steps, it, in my opinion, belongs in an appropiately named utility class so that the details are hidden and the code in place (thus reducing error probability).
If you weigh it against the gains, those few additional lines are not really something to worry about.

Georg Fritzsche
life would be so much easier if Stroustrop would allow finally into c++ (he flatly refuses to allow it, he feels you should have a class every time)
pm100
To be honest, i rarely feel the need for what the OP mentions because every repeated resource usage pattern *should* be in a utility class. Added bonus - you don't have to remember the resource handling details.
Georg Fritzsche
@pm100: No, you've got it upside down. Finally would mean I'd have to write cleanup code every time I use the class. RAII, relying on the destructor, means I can write the cleanup code *once* per class. How is finally a good idea again?
jalf
@jalf: Amen! Finally is an abomination!
Drew Hall
Finally is a good idea when you *want* to write cleanup code that only occurs in one place, and is inconsistent between different users of the same resource. i.e, never. No, I mean: e.g, when you want to add some quick tracing to something, or write a transaction (which is almost always unique and used in only one place). Obviously you can write a class to represent your transaction, but it can get a bit enterprise-y if you *have* to do that, hence various scope guards, which are fine (better, even) unless you're used to finally and uncomfortable with learning coding styles.
Steve Jessop
if I acquire something as a one off - then I want to use finally to release it. Otherwise I have to write a one off class. I know that for common resource classes I must write wrapper classes (and my code is full of them). I object to being forced to do in every case
pm100
+8  A: 

shared_ptr provides the possibility to specify a custom deleter. When the pointer needs to be destroyed, the deleter will be invoked and can do whatever cleanup actions are necessary. This way more complicated resources than simple pointers can be managed with this smart pointer class.

sth
so does std::unique_ptr.
sellibitze
+3  A: 

I have to admit I don't really see the point. Writing a RAII wrapper from scratch is ridiculously simple already. There's just not much work to be saved by using some kind of predefined wrapper:

struct scoped_foo : private boost::noncopyable {
  scoped_foo() : f(...) {}
  ~scoped_foo() {...}

  foo& get_foo() { return f; }

private:
  foo f;
};

Now, the ...'s are essentially the bits that'd have to be filled out manually if you used some kind of general RAII template: creation and destruction of our foo resource. And without them there's really not much left. A few lines of boilerplate code, but it's so little it just doesn't seem worth it to extract it into a reusable template, at least not at the moment. With the addition of lambdas in C++0x, we could write the functors for creation and destruction so concisely that it might be worth it to write those and plug them into a reusable template. But until then, it seems like it'd be more trouble than worth. If you were to define two functors to plug into a RAII template, you'd have already written most of this boilerplate code twice.

jalf
Funny, i wrote my update at the same time.
Georg Fritzsche
lambdas, yes thats what i was thinking about . sorry for not mentioning this in my question ( it was in my mind though)
Yogesh Arora
As far as I know, C++0x doesn't define such a template. Perhaps because it's so simple to do there's not much point. Perhaps they're waiting for Boost or other third parties to define one, and let it prove itself in the real world before standardizing it. At the moment, we don't yet know if 1) it's worth the effort and 2) if there are any non-obvious gotchas that the template should be able to handle.
jalf
A: 

I was thinking about something similar:

template <typename T>
class RAII {
    private:
        T (*constructor)();
        void (*destructor)(T);
    public:
        T value;
        RAII(T (*constructor)(), void (*destructor)(T)) : 
                    constructor(constructor), 
                    destructor(destructor) {
            value = constructor();
        }
        ~RAII() {
            destructor(value);
        }
};

and to be used like this (using OpenGL's GLUquadric as an example):

RAII<GLUquadric*> quad = RAII<GLUquadric*>(gluNewQuadric, gluDeleteQuadric);
gluSphere(quad.value, 3, 20, 20)
Lie Ryan