Browse DevX
Sign up for e-mail newsletters from DevX


Use Local Classes for Proper Cleanup in Exception-enabled Apps : Page 3

While exceptions help with code reliability and data integrity, they can also complicate it. Proper cleanup is essential to making sure that your data is safe and that resources are always released. Learn how to use a local class's destructor to ensure the unconditional execution of cleanup code.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

A Synergic Combination
C++ ensures that destructors of auto objects execute when an exception occurs as part of the stack unwinding process. Take advantage of this behavior and move unconditional cleanup code into a destructor. This technique is hardly new, of course. However, the properties of local classes enable you to refine it.

You want to add cleanup code to func() which will execute unconditionally. More importantly, you want this code to execute upon leaving func(), but not sooner. To achieve these goals, you will combine the deterministic execution of auto objects' destructors and the properties of local classes. This synergic combination imitates the functionality of Java's finally.

First, define a local class before the first throw statement and add cleanup code to its destructor. This class should have only one member: a public destructor. Then, instantiate an object of this class immediately after the class's definition:

void func() { try { struct Finally { ~Finally() { cleanup(); SMS_sysadmin("terminating");} } finalizer; if (something_bad) //#a1 throw X(); //#b1 otherwise continue normally } catch (X& x) // #a2 { exit(1); } //#b2 we get here only if no exception was thrown }

That's all! When func() exits, either normally or due to an exception, the destructor of finalizer will execute unconditionally and perform the necessarily process termination procedures.

The Grand Finale
You might argue that there's no need to use a local class to perform this feat: any auto object's destructor will do. However, because Finally is a local class, other programmers won't be able to create instances thereof elsewhere. More importantly, local classes have no linkage. Therefore, you can define classes with the same name in different scopes without risking name clashes:

void func() { class Local{} loc;//#1 } int main() { class Local {} loc;//#2 OK, doesn't clash with #1 }

This property enables you to use a uniform name for such "disposable classes" in all your projects. As a security bonus, neither the local class' name nor the names of its member functions will be stored in an executable/DLL file. Consequently, crackers attempting to decompile your binaries will have a hard time indeed.

Danny Kalev is a certified system analyst and software engineer specializing in C++. He was a member of the C++ standards committee between 1997 and 2000 and has since been involved informally in the C++0x standardization process. He is the author of "The ANSI/ISO Professional C++ Programmer's Handbook" and "The Informit C++ Reference Guide: Techniques, Insight, and Practical Advice on C++."
Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date