home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #18 / NN_1992_18.iso / spool / comp / lang / cplus / 12462 < prev    next >
Encoding:
Text File  |  1992-08-17  |  3.0 KB  |  83 lines

  1. Newsgroups: comp.lang.c++
  2. Path: sparky!uunet!microsoft!hexnut!jimad
  3. From: jimad@microsoft.com (Jim Adcock)
  4. Subject: Re: Best solution for this problem?
  5. Message-ID: <1992Aug17.231722.13229@microsoft.com>
  6. Date: 17 Aug 92 23:17:22 GMT
  7. Organization: Microsoft Corporation
  8. References: <aldavi01.713596256@starbase.spd.louisville.edu>
  9. Lines: 72
  10.  
  11. In article <aldavi01.713596256@starbase.spd.louisville.edu> aldavi01@starbase.spd.louisville.edu (Arlie Davis) writes:
  12. |I am designing a class which must decide during its construction how it should
  13. |behave.  "How it should behave" is normally decided through virtual methods
  14. |in the class, with different behavior in different derived children.
  15. |However, that solution is only applicable when the behavior of the class is
  16. |decided *before* its construction.  However, this class *must* be able to
  17. |decide which kind of child it wants to be during its construction.
  18.  
  19. Conceptually, what you want to do is inherit from a reference.  Unfortunately,
  20. C++ does not permit that.  So, one does the next best thing, one writes a
  21. class that acts like a reference, and then you inherit from that.  IE a 
  22. "smart reference class."  Unfortunately, C++ also makes writing "smart
  23. reference classes" a pain as has been noted many times.  [support operator.()]
  24.  
  25. Below find a simple example of inheriting from a "smart reference class."
  26. "designated_parent" is the "smart reference class" that one inherits from.
  27. Male_offspring then inherits from the "smart reference class" so that its
  28. behavoir can be selected at construction time.  Just for fun, I use this
  29. feature to demonstrate objects inheriting runtime behavoir from themselves ;-)
  30.  
  31. In a more practical approach, people have used these kinds of approaches where
  32. one program runs transparently under more than one kind of GUI system, automa-
  33. gically adjusting its runtime behavior to the GUI system currently in use.
  34.  
  35. // 
  36.  
  37. extern "C" void printf(const char*, ...);
  38.  
  39. class parent
  40. {
  41. public:
  42.     virtual void parentage() { printf("parent "); }
  43. };
  44.  
  45. class b : public parent
  46. {
  47. public:
  48.     virtual void parentage() { printf("b "); }    
  49. };
  50.  
  51. class designated_parent : public parent
  52. {
  53. protected:
  54.     parent& designate;
  55. public:
  56.     designated_parent(parent& p) : designate(p) { }
  57.     designated_parent(designated_parent& dp) : designate(dp)
  58.     { }
  59. // in general, with reference classes like this you either need overloadable
  60. // operator dot, or you have to write a forwarding function for each
  61. // member function as follows:
  62.     virtual void parentage() { designate.parentage(); }
  63. };
  64.  
  65. class male_offspring : public designated_parent
  66. {
  67. public:
  68.     male_offspring(parent& p) : designated_parent(p) { }
  69.     virtual void parentage() { printf("son of a "); 
  70.         designate.parentage(); }
  71. };
  72.  
  73. main()
  74. {
  75.     b fifi; fifi.parentage(); printf("\n");
  76.     male_offspring foofoo(fifi); foofoo.parentage(); printf("\n");
  77.     male_offspring barbar(foofoo); barbar.parentage(); printf("\n");
  78. #ifdef OPTIONAL
  79.     male_offspring wickywoo = wickywoo; wickywoo.parentage(); printf("\n");
  80.     // Oh, I'm my own grandpa....
  81. #endif
  82. }
  83.