Path: utzoo!utgpu!watserv1!watmath!att!dptg!ulysses!andante!alice!shopiro From: shopiro@alice.UUCP (Jonathan Shopiro) Newsgroups: comp.lang.c++ Subject: Re: Question for language lawyers Summary: Assignment to ``this'' is deprecated Message-ID: <10483@alice.UUCP> Date: 15 Feb 90 15:48:08 GMT References: <52.UUL1.3#5109@pantor.UUCP> Organization: AT&T Bell Laboratories, Murray Hill NJ Lines: 98 In article <52.UUL1.3#5109@pantor.UUCP>, richard@pantor.UUCP (Richard Sargent) writes: > [Long discussion omitted -- essentially the problem is to create an object without knowing its exact type. Sargent gives a solution (credited to Martin Miller) that has the user code create a base class object and then the base class constructor uses an assignment to this to arrange that the result is the appropriate derived class object.] Please don't use this technique. Assignment to ``this'' results in a warning in C++ 2.0 and will probably be disallowed completely in future versions. It has always been an ugly wart on the language and getting rid of it will allow a much better implementation of constructors. Following is a revision of Sargent's example code with assignment to ``this'' eliminated. The only change to the interface is that the user now says BASE::new_BASE() where he used to say new BASE Also some error checking has been moved from run-time to compile-time and the code is a little cleaner and more efficient. Otherwise I have tried to minimize the changes to Sargent/Miller's code. // sample showing how a BASE class static member function can be // used to create DERIVED class objects #include short maketype; // simple way to determine what DERIVED class // the BASE() class constructor creates class BASE { public: BASE(); static BASE* new_BASE(); virtual ~BASE() {} // if wanted virtual void iam() { cout << "I am a BASE()\n"; } }; class DERIVED1 : public BASE { public: virtual ~DERIVED1() {} // if wanted virtual void iam() { cout << "I am a DERIVED1()\n"; } }; class DERIVED2 : public BASE { public: virtual ~DERIVED2() {} // if wanted virtual void iam() { cout << "I am a DERIVED2()\n"; } }; BASE* BASE::new_BASE() { switch( maketype ) { case 0: return new BASE; case 1: return new DERIVED1; case 2: return new DERIVED2; } } main() { maketype = 0; BASE *bp0 = BASE::new_BASE; bp0->iam(); delete bp0; cout << "\n"; maketype = 1; BASE *bp1 = BASE::new_BASE; bp1->iam(); delete bp1; cout << "\n"; maketype = 2; BASE *bp2 = BASE::new_BASE; bp2->iam(); delete bp2; } If the function BASE::new_BASE is to be used to create all objects in the BASE hierarchy, then you should make all the constructors protected and make all the derived classes friends of the base class. If you have an old version of C++ without static member functions, make new_BASE an external function and make it a friend of all the classes in the hierarchy. -- Jonathan Shopiro AT&T Bell Laboratories, Warren, NJ 07060-0908 research!shopiro (201) 580-4229