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

  1. Path: sparky!uunet!pipex!demon!cix.compulink.co.uk!vadim
  2. Newsgroups: comp.lang.c++
  3. From: vadim@cix.compulink.co.uk (Vadim Lebedev)
  4. Subject: Re: Object metamorphosis - can
  5. Reply-To: vadim@cix.compulink.co.uk
  6. Date: Wed, 19 Aug 1992 16:44:38 +0000
  7. Message-ID: <memo.584473@cix.compulink.co.uk>
  8. Sender: usenet@gate.demon.co.uk
  9. Lines: 104
  10.  
  11. In-Reply-To: <1992Aug17.223629.5722@fcom.cc.utah.edu> swillden@news.ccutah.edu (Shawn Willden)
  12.  
  13. TITLE: Object metamorphosis - can/should it be done?
  14.  
  15. In article   : <1992Aug17.223629.5722@fcom.cc.utah.edu>
  16.  swillden@news.ccutah.edu (Shawn Willden)
  17.  writes:
  18. > I ran across some interesting Objective-C code the other day and I 
  19. > wondered if there is some way to implement it in C++.  Then I wondered
  20. > if it was a good idea to try.  Anyway, the concept is that an object
  21. > can be asked to mutate into an object of a different type.  Under
  22. > Objective-C's concept of an object, any object can mutate to essentially
  23. > any other type because all messages are resolved at run-time.  In C++'s
  24. > static system this is not possible, however, it seems to me that there 
  25. > is at least one case in which it might be possible in C++ and maybe even 
  26. > useful.  Given a base class pointer or reference to a derived class
  27. > object, it should be possible to replace the derived class object with
  28. > an object of another derived type.  Something like:
  29. [ message deleted]
  30.  
  31. You canc achieve your goal using placement new syntax:
  32.  
  33. class Mutator { } mutator;
  34.  
  35. class Butterfly
  36.         {
  37.  protected:
  38.     // Allocate abject in-place 
  39.     void *new(size_t,  void *t)  { return t; }
  40.     
  41.     // Mutating constructor
  42.     Butterfly(Mutator , const Butterfly &) { // Do nothing here }
  43.  
  44.         // some data here.
  45.         public:
  46.  
  47.  // allocate a storage chunk capable to accomodoate all of the 
  48.  // variantes 
  49.  void *new(size_t s) {
  50.   return new char[MAX(sizeof(Pupa), sizeof(Adult), sizeof(Butterfly),s)];
  51.   }
  52.  
  53.         Butterfly()                     {...}
  54.         Butterfly(Butterfly& b)         {...}
  55.         // The metamorphose() function will turn an object of some
  56.         // descendant type into an object of some other descendant 
  57.         // type.
  58.         virtual void metamorphose() = 0;
  59.         virtual void report()           {cout << "I'm a generic butterfly\n";}
  60.         };
  61.  
  62. class Pupa : public Butterfly
  63.         {
  64.         // Note that this method is private.  This is to insure that
  65.         // it is *only* called through the base class interface. 
  66.         void metamorphose();
  67.         public:
  68.         Pupa()                  {...}
  69.         void report()           {cout << "I'm a caterpillar\n";}
  70.  protected:
  71.     // Mutating constractor
  72.     Pupa(Mutator m, const Butterfly &b) : Butterfly(m, b) { }  
  73.         };
  74.  
  75. class Adult : public Butterfly
  76.         {
  77. friend class Pupa;
  78.         // Again, this method is private.
  79.         void metamorphose();
  80.         public:
  81.         Adult()                                 {...}
  82.         Adult(Butterfly& b) : Butterfly(b)      {...}
  83.         void report()           {cout << "I'm a real butterfly\n";}
  84.  protected:
  85.     Adult(Mutator m, const Pupa &p) : Butterfly(m, p) { }  
  86.  
  87.         };
  88.  
  89. void Pupa::metamorphose()
  90.         {
  91.  new (this) Adult(mutator, *this);
  92.         }
  93.  
  94. main()
  95.         {
  96.         Butterfly *fred = new Pupa;
  97.  
  98.         fred->report();
  99.         fred->metamorphose();
  100.         fred->report();
  101.         }
  102.  
  103.  
  104. Of course this trick works only on heap allocated objects, for automatic
  105. or static objects one should take care that the base and all derived classes
  106. has the same sizes. 
  107.  
  108. -----------------------------------------------------------------------
  109. Vadim Lebedev                      |   Kortex International
  110. vadim@cix.compulink.co.uk          |   139-147 av. Paul-Vaillant Couturier
  111.                                    |   93126 La Courneuve - CEDEX, France
  112.  
  113.  
  114.