Re: RAII not always applicable?
I still think that you can refactor any class that has "construct dummy,
initialize later" behavior into two classes: a shared_ptr-like handler
and a _real_ class with stronger encapsulation and invariants.
Maybe the problem is sometimes developers rush to get a (relatively
less important) functionality done, and end up with one bulk class
instead of a cleaner design (I know I have :-) I would like to hear
comments on this.
If we take a plain (and perfect) example of RAII usage. Il looks like
this:
{
RAIIResource resource;
resource.use(); /// very simple usage
} // auto-release
Now, it may be insufficient if we need to know the address of the
object before it is initialized (e.g. to pass it by reference), as in
your example:
you could use a smart pointer, or a custom wrapper:
std::shared_ptr<T> val;
std::cin >> val;
First, I would use boost::optional rather than std::shared_ptr, unless
shared ownership was really required. The former doesn't allocate
anything on the heap and is therefore faster.
But the problem that still remains is that whereas T can now be a full
RAII objct, the usage is still a two-phase init with all its burden:
std::shared_ptr<T> val; // dummy init
std::cin >> val; // perhaps full init
if( val ) { // defensive if required :(
val->use();
}
You could call this pattern "Making two-phase init out of single-phase
init class". It is very useful in some situations. I found it useful
once when implementing a problem solver. You would request searching
for the best solution (but usually it means infinately long) and
request a stop and return of the best solution found so far:
void OnButtonSolve() {
solver.start();
}
void OnButtonStop() {
Solution sol = solver.stop();
store( sol );
}
Functions 'start' and 'stop' were respectively creating and joining
+destroying a boost::thread, which is somewhat RAII, in-place with the
help of boost::optional.
About OP's second example... A real-world example would help in finding
a better design.
The example I provided is from the being-developed Boost library:
Boost.Coroutine. You can obtain it from Boost Vault:
http://www.boostpro.com/vault/index.php?PHPSESSID=ebfe7ae73e7578929b21aaa732182fe1&direction=0&order=&directory=Concurrent%20Programming
I didn't want to quote too much in the post. It has a good
documentation, and the example is taken literarly from there.
Regards,
&rzej
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]