B
Buster
Markus said:I try to express the RAII design pattern/idiom in C++ language terms.
I think that the virtual methods are needed so that they can be
overloaded.
"Overridden". You're right, I think, but a real example would help to
convince me. I can't think of a situation where you know at compile time
that there needs to be some RAII done, but you don't know exactly what
the resource is going to be until run time. Enlighten me?
Do you know a wording which would achieve a similar effect with code
generation by the templates?
Sure. Check out the standard C++ library algorithms. Here's a simple
example. Notice there's no code at all corresponding to the Concept.
// Concept: Transmogrifiable.
// If x is an object of a type T which models
// the Transmogrifiable concept, then the
// following expression is valid:
//
// x.transmogrify ();
// Postcondition: x is transmogrified.
// Algorithm: transmogrify_n
// If x is an object of a type T which models
// the Transmogrifiable concept, and n is an integer,
// then the following expression is valid:
//
// transmogrify_n (x, n);
// Postcondition: x is transmogrified n times.
template <typename T, typename Integer>
void transmogrify_n (T & x, Integer n)
{
for (Integer i (0); i < n; ++ i)
{
x.transmogrify ();
}
}
The difference between RAII2 and RAII3 is this:
- RAII2 uses delegation over the variable "_m_p". A method pair can be
selected at run time.
- RAII3 uses private inheritance to specify construction and
destruction as an implementation detail that should not be visible to
the clients of the class. The selction is done at compile time.
The adapter or wrapper is needed if your class X offers two related
methods (a specific pair) to which calls should be encapsulated by the
RAII technique.
Sure. But why not use the constructor and destructor?
The methods "begin" and "end" should be kept private as far as
possible because they play their role as a virtual constructor and
destructor.
Ah-hah. I suppose so.
Your "X_MP_adapter" sketch looks like an approach that is covered by
the class "std::auto_ptr" already.
I am interested in the RAII handling of data structures that are not
concerned with a managed pointer.
Would you like to look at an other specific implementation?
- http://zthread.sourceforge.net/html/classZThread_1_1Guard.html
- http://zthread.sourceforge.net/html/classZThread_1_1LockedScope.html
I see also use cases besides synchronization in the document "Memory
model for multithreaded C++".
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1680.pdf
I would like to use the class "std::atomic_int" with my suggestion.
Such an integer value will be reset (e.g. 0 as default) in the
destructor.
I guess that the class "std::msync" will become another interesting
candidate for some applications.
If it works, go for it. I think you're wasting your time trying to solve
a very general problem, when the solution is easy (write a class with a
constructor and destructor) for any particular instance of the problem.