The constructor might screw up, because of f(), so the destructor might never get called. Can I circumvent the problem by allocating p_ at the end? Is this good style? |
MEEEP. Wrong way of thinking.
Not the order in the initialization list (the thing after ":") matters, but the
order of declaration in the class body (sic). So for your case, p will already be assigned after f is called, just because you declare p_ after l_ in your class declaration. Be aware of any cross references in the member variables. You have to order the declaration of the members, and
not the order in which you assign values. (This is a very common mistake).
Now for your question: Yes, RAII can (and should) be used here, if you expect f to throw anything (or if you care what happens should it throw). Many code designers just define something like "Should exceptions happen, then I am already paid and in Florida. Devil-may-care." ;-) (Which may be totally ok depending what code you write..)
Best form is, you just use the provided std::tr1::shared_ptr if it is already provided for your environment. This' may be a bit overkill for you (it's a fully fledged shared pointer including reference counting and everything). You may also consider std::tr1::unique_ptr or std::auto_ptr if p_ is not assigned to anything.
If you really want to implement your own RAII class wrapper, CLASS2W is a good start. You'll need some method to get to the wrapped value, though. operator*() and operator->() are common choices. The resulting construct is then called "smart pointer" (like std::tr1::shared_ptr). You may also just provide a standard-getter.
To make it work, just use a normal class (not a pointer) in CLASS1:
1 2 3 4
|
class CLASS1 {
...
CLASS2W c1_;
...
|
As you and Disch have already figured out, any member that has been fully constructed will be destructed properly in case of exceptions ;). By the way, this is a general rule in C++ which is very holy to the creators:
If any constructor finished properly, the class destructor will be called. You can rely on this, even if the class is a (wrapper)-member of another. RAII is all about this guarantee.
Ciao, Imi.