Finally in C++
The standard answer is to use some variant of resource-allocation-is-initialization abbreviated RAII. Basically you construct a variable that has the same scope as the block that would be inside the block before the finally, then do the work in the finally block inside the objects destructor.
try {
// Some work
}
finally {
// Cleanup code
}
becomes
class Cleanup
{
public:
~Cleanup()
{
// Cleanup code
}
}
Cleanup cleanupObj;
// Some work.
This looks terribly inconvenient, but usually there's a pre-existing object that will do the clean up for you. In your case, it looks like you want to destruct the object in the finally block, which means a smart or unique pointer will do what you want:
std::unique_ptr<Object> obj(new Object());
or modern C++
auto obj = std::make_unique<Object>();
No matter which exceptions are thrown, the object will be destructed. Getting back to RAII, in this case the resource allocation is allocating the memory for the Object and constructing it and the initialization is the initialization of the unique_ptr.
No. The Standard way to build a finally like way is to separate the concerns (http://en.wikipedia.org/wiki/Separation_of_concerns) and make objects that are used within the try block automatically release resources in their destructor (called "Scope Bound Resource Management"). Since destructors run deterministically, unlike in Java, you can rely on them to clean up safely. This way the objects that aquired the resource will also clean up the resource.
One way that is special is dynamic memory allocation. Since you are the one aquiring the resource, you have to clean up again. Here, smart pointers can be used.
try {
// auto_ptr will release the memory safely upon an exception or normal
// flow out of the block. Notice we use the "const auto_ptr idiom".
// http://www.gotw.ca/publications/using_auto_ptr_effectively.htm
std::auto_ptr<A> const aptr(new A);
}
// catch...
If for some strange reason you don't have access to the standard libraries, then it's very easy to implement as much as you need of a smart pointer type to handle the resource. It may look a little verbose, but it's less code than those nested try/catch blocks, and you only have to define this template once ever, instead of once per resource that needs management:
template<typename T>
struct MyDeletable {
explicit MyDeletable(T *ptr) : ptr_(ptr) { }
~MyDeleteable() { delete ptr_; }
private:
T *ptr_;
MyDeletable(const MyDeletable &);
MyDeletable &operator=(const MyDeletable &);
};
void myfunction() {
// it's generally recommended that these two be done on one line.
// But it's possible to overdo that, and accidentally write
// exception-unsafe code if there are multiple parameters involved.
// So by all means make it a one-liner, but never forget that there are
// two distinct steps, and the second one must be nothrow.
Object *myObject = new Object();
MyDeletable<Object> deleter(myObject);
// do something with my object
return;
}
Of course, if you do this and then use RAII in the rest of your code, you'll eventually end up needing all the features of the standard and boost smart pointer types. But this is a start, and does what I think you want.
The try ... catch approach probably won't work well in the face of maintenance programming. The CLEAN UP block isn't guaranteed to be executed: for example if the "do something" code returns early, or somehow throws something which is not an Exception. On the other hand, the destructor of "deleter" in my code is guaranteed to be executed in both those cases (although not if the program terminates).