advertisement
Login | Register   
  Include Code  Search Tips
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Which additional problems can the technique demonstrated here solve? Which problems, if any, does it create? Post your suggestions in the c++.general discussion group.
Partners & Affiliates
advertisement
advertisement
advertisement
advertisement
Average Rating: 4.3/5 | Rate this item | 4 users have rated this item.
Managing Objects' Construction Order (cont'd)
Dealing with the Construction Order Dependency
Will this application run as expected? Maybe. Everything depends on the order in which the objects admin and lf are constructed. If admin is constructed first, lf's constructor can call admin.getfilename() safely. If, however, your linker chooses the reverse construction order (and it's at liberty to do so!) all hell breaks loose. The call to admin.getfilename() would cause undefined behavior in this case. As a workaround, you can move the definitions of lf and admin into the same translation unit:

#include "admin.h"
#include "logfile.h"
Admin admin;
Logfile lf(admin.getfilename());
int main()
{
//application code
return 0;
}
advertisement
While this tweak ensures that admin is constructed before lf, it's still problematic. The implementer of main.cpp must know the exact order in which the objects should be constructed and declare them accordingly. In real projects, there could be hundreds of objects in dozens of translation units. Grouping all objects in a single translation unit is rarely an option. Besides, future maintainers of main.cpp might mistakenly change the order of definitions, not knowing that by doing so they're wreaking havoc. To conclude, this isn't a plausible solution.

Getting Rid of Construction Order Dependency
Instead of forcing all users to know the precise construction order, you want a mechanism of controlling it. Fortunately, such a mechanism is readily available and is quite simple: replace every global object with a local static object inside an accessor function. For example, instead of the global admin object, use the following accessor function:


//getadmin.cpp
#include "admin.h"
Admin& getadmin()
{
//create a local static object when this function is
//called for the first time
static Admin admin;
return admin;
}
Similarly, replace the global lf with an accessor function. Notice that in the following function, the construction of lf is guaranteed to succeed because the call to getadmin() always returns a reference to a valid Admin object:

//getlogfile.cpp
#include "amdmin.h"
#include "logfile.h"
Logfile& getlogfile()
{
static Logfile lf(getadmin().getfilename());//safe
return lf;
}
This technique neatly solves the order dependency problem. When you call an accessor function for the first time it constructs the local static object and returns a reference to it which you can use safely. This way, you actually determine the construction order of each object! You can call an accessor function from every translation unit. Moreover, subsequent calls return a reference to the same object so you don't need global objects anymore.

Final Refinements
The use of accessor functions solved the construction order dependency but there's still one problem left. How do you ensure that lf is constructed before main() starts? The solution is using a global reference to Logfile that is initialized by the proper accessor function:


#include "getlogfile.h"
Logfile & ref=getlogfile(); //initialized before main()
int main()
{
//..
return 0;
}
Previous Page: Advice on Code Organization  
Danny Kalev is a system analyst and software engineer with 13 years of experience, specializing in C++ and object-oriented analysis and design. He is a member of the ANSI C++ standardization committee and the author of ANSI/ISO C++ Professional Programmer's Handbook (Que, 1999, ISBN: 0789720221). Reach him at dannykk@inter.net.il.
Page 1: IntroductionPage 3: Dealing with the Construction Order Dependency
Page 2: Advice on Code Organization  
Please rate this item (5=best)
 1  2  3  4  5
advertisement