home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #30 / NN_1992_30.iso / spool / comp / lang / cplus / 17874 < prev    next >
Encoding:
Text File  |  1992-12-12  |  4.7 KB  |  146 lines

  1. Path: sparky!uunet!olivea!charnel!rat!usc!zaphod.mps.ohio-state.edu!cs.utexas.edu!convex!egsner!adaptex!sdf!carden
  2. From: carden@sdf.lonestar.org (Jack Carden)
  3. Newsgroups: comp.lang.c++
  4. Subject: Re: Idempotent header file proposal
  5. Summary: alternate proposal
  6. Keywords: alternative ideas header file organization
  7. Message-ID: <Bz0xp6.E8H@sdf.lonestar.org>
  8. Date: 10 Dec 92 03:29:29 GMT
  9. Followup-To: comp.lang.c++
  10. Organization: sdf full-shell Public Access Unix - Dallas, TX - 214/436-3281
  11. Lines: 133
  12.  
  13. In article <1992Nov19.090742.23696@cbfsb.cb.att.com> nh@cbnewsg.cb.att.com (nicholas.hounsome) writes:
  14. |One problem with C++ is that when used properly it requires huge
  15. |numbers of header files most of which are included multiple times.
  16. |Of course I know that there is the crude workaround :
  17. |
  18. |#ifndef HEADER_H
  19. |#define HEADER_H
  20. |
  21. |stuff
  22. |
  23. |#endif
  24. |
  25. |But the preprocessor still has to find, open , and read the whole file
  26. |so it does not realy gain you any efficiency.
  27.  
  28. Please allow me to add another idea to this discussion.  While attending
  29. the USENIX C++ Conference, in Denver, 1988, I heard an attendee explain
  30. his method for controlling include file use.  I am sorry that I can't
  31. give proper credit to this person, but I liked his ideas so much that I
  32. adopted them then and have used them since in all the development projects
  33. I have tackled.  I still like this approach better than precompiled header
  34. files (unless I would gain confidence that the preprocessor "understands"
  35. my class relationships.)
  36.  
  37. The approach requires some discipline in header file creation, but I
  38. haven't found this to be a problem.  One begins with the idea of a master
  39. include file for the project or the component to be created.  The master
  40. include file will include all other required files, but only those required
  41. in the particular "module" under compilation.  The master file will know
  42. which files to include because the author has used #define to indicate
  43. required files (generally one class per include file.)
  44.  
  45. The individual class include files will generally look like this:
  46.  
  47. == classA.h ==
  48. #ifndef Pass2                   // test for appropriate "pass" on this file
  49. #define Incl_classB             // indicate the need for classB definitions
  50. #else                           // otherwise proceed with classA definitions
  51.  
  52. class classA {
  53. protected:
  54.       void foo(classB &);
  55. ...
  56. };
  57. #endif
  58.  
  59.  
  60. == classB.h ==
  61. #ifndef Pass2
  62. #define Incl_classC
  63. #define Incl_assert  // can also indicate the need for standard include files
  64. #else
  65.  
  66. class classB : public classC {
  67. ...
  68. };
  69. #endif
  70.  
  71. The master include file will generally look like this:
  72.  
  73. == master.h ==
  74. // begin first pass of all project-related include files
  75. #ifdef Incl_classA  // inclusion of classA preceeds classB because of dependency
  76. #include "classA.h"
  77. #endif
  78.  
  79. ...
  80.  
  81. #ifdef Incl_classB  // inclusion of classB preceeds classC because of dependency
  82. #include "classB.h"
  83. #endif
  84.  
  85. ...
  86.  
  87. #ifdef Incl_classC  // inclusion of classC follows classA and classB
  88. #include "classC.h"
  89. B
  90. #endif
  91.  
  92. ...
  93.  
  94. // include any "standard" include files as requested
  95. #ifdef Incl_assert
  96. #include <assert.h>
  97. #endif
  98.  
  99. // begin second pass of all project-related include files.
  100. // Note the inverted order of inclusion.
  101. #define Pass2
  102. #ifdef Incl_classC  // inclusion of classC lays the foundation for classA and classB
  103. #include "classC.h"
  104. #endif
  105.  
  106. ...
  107.  
  108. #ifdef Incl_classB  // inclusion of classB preceeds classA because of dependency
  109. #include "classB.h"
  110. #endif
  111.  
  112. ...
  113.  
  114. #ifdef Incl_classA  // inclusion of classA follows classB because of dependency
  115. #include "classA.h"
  116. #endif
  117.  
  118. All source files will generally look like this:
  119. == classA.C
  120. #define Incl_classA             // indicate the need for classA definitions.
  121. #define Incl_classB             // we can also request any others we want.
  122.                                 // we assume that classA may request others.
  123. #define Incl_classD             // we might require other classes as well.
  124. #include "master.h"
  125.  
  126. void classA::
  127.      foo(classB &)
  128. {
  129. ...
  130. }
  131.  
  132. This organization seems to provide two benefits:
  133.    1) It forces the organization of include files to be consistent and
  134.       it causes the designer to consider the appropriate order for 
  135.       inclusion in master.h thereby prohibiting circular references.
  136.    2) It limits the pre-processor to two scans of each of the include files
  137.       for each compilation.
  138.  
  139. Are there over-simplifications that I have missed?  This approach has
  140. proven very satisfactory (at least in my view) on three different projects.
  141.  
  142. Jack Carden                             The eye may see for the hand,
  143. Software Engineering                    but not for the mind.
  144. Carrollton, TX  75006                             <Thoreau, 1849>
  145. Internet: carden@sdf.lonestar.org
  146.