home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!pipex!demon!cix.compulink.co.uk!vadim
- Newsgroups: comp.lang.c++
- From: vadim@cix.compulink.co.uk (Vadim Lebedev)
- Subject: Re: Object metamorphosis - can
- Reply-To: vadim@cix.compulink.co.uk
- Date: Wed, 19 Aug 1992 16:44:38 +0000
- Message-ID: <memo.584473@cix.compulink.co.uk>
- Sender: usenet@gate.demon.co.uk
- Lines: 104
-
- In-Reply-To: <1992Aug17.223629.5722@fcom.cc.utah.edu> swillden@news.ccutah.edu (Shawn Willden)
-
- TITLE: Object metamorphosis - can/should it be done?
-
- In article : <1992Aug17.223629.5722@fcom.cc.utah.edu>
- swillden@news.ccutah.edu (Shawn Willden)
- writes:
- >
- > I ran across some interesting Objective-C code the other day and I
- > wondered if there is some way to implement it in C++. Then I wondered
- > if it was a good idea to try. Anyway, the concept is that an object
- > can be asked to mutate into an object of a different type. Under
- > Objective-C's concept of an object, any object can mutate to essentially
- > any other type because all messages are resolved at run-time. In C++'s
- > static system this is not possible, however, it seems to me that there
- > is at least one case in which it might be possible in C++ and maybe even
- > useful. Given a base class pointer or reference to a derived class
- > object, it should be possible to replace the derived class object with
- > an object of another derived type. Something like:
- [ message deleted]
-
- You canc achieve your goal using placement new syntax:
-
- class Mutator { } mutator;
-
- class Butterfly
- {
- protected:
- // Allocate abject in-place
- void *new(size_t, void *t) { return t; }
-
- // Mutating constructor
- Butterfly(Mutator , const Butterfly &) { // Do nothing here }
-
- // some data here.
- public:
-
- // allocate a storage chunk capable to accomodoate all of the
- // variantes
- void *new(size_t s) {
- return new char[MAX(sizeof(Pupa), sizeof(Adult), sizeof(Butterfly),s)];
- }
-
- Butterfly() {...}
- Butterfly(Butterfly& b) {...}
- // The metamorphose() function will turn an object of some
- // descendant type into an object of some other descendant
- // type.
- virtual void metamorphose() = 0;
- virtual void report() {cout << "I'm a generic butterfly\n";}
- };
-
- class Pupa : public Butterfly
- {
- // Note that this method is private. This is to insure that
- // it is *only* called through the base class interface.
- void metamorphose();
- public:
- Pupa() {...}
- void report() {cout << "I'm a caterpillar\n";}
- protected:
- // Mutating constractor
- Pupa(Mutator m, const Butterfly &b) : Butterfly(m, b) { }
- };
-
- class Adult : public Butterfly
- {
- friend class Pupa;
- // Again, this method is private.
- void metamorphose();
- public:
- Adult() {...}
- Adult(Butterfly& b) : Butterfly(b) {...}
- void report() {cout << "I'm a real butterfly\n";}
- protected:
- Adult(Mutator m, const Pupa &p) : Butterfly(m, p) { }
-
- };
-
- void Pupa::metamorphose()
- {
- new (this) Adult(mutator, *this);
- }
-
- main()
- {
- Butterfly *fred = new Pupa;
-
- fred->report();
- fred->metamorphose();
- fred->report();
- }
-
-
- Of course this trick works only on heap allocated objects, for automatic
- or static objects one should take care that the base and all derived classes
- has the same sizes.
-
- -----------------------------------------------------------------------
- Vadim Lebedev | Kortex International
- vadim@cix.compulink.co.uk | 139-147 av. Paul-Vaillant Couturier
- | 93126 La Courneuve - CEDEX, France
-
-
-