chatty%FRLRI61.BITNET@CUNYVM.CUNY.EDU (02/08/91)
// the following program is accepted by both g++ and cfront 2.0. // It leads to the suprising thing that a virtual method of class B is // called before the body of the constructor is entered. // I think ARM, p47, s5.1, forbids the use of 'this' in member // initialization. // any comments? extern "C" void printf (const char*, ...); class A { public: A () {} virtual void foo () {printf ("A::foo\n");} }; class Z { public: Z (A* a) {a->foo ();} }; class B : public A { public: Z z; B () : A (), z (this) {printf ("B::B\n");} // legal?! void foo () {printf ("B::foo\n");} }; main () { B b; } // % a.out // B::foo // B::B Stephane Chatty chatty@lri.lri.fr, chatty@frlri61.bitnet
jak@cs.brown.edu (Jak Kirman) (02/09/91)
In article <9102080900.AA19725@lri.lri.fr> chatty%FRLRI61.BITNET@CUNYVM.CUNY.EDU writes: // the following program is accepted by both g++ and cfront 2.0. // It leads to the suprising thing that a virtual method of class B is // called before the body of the constructor is entered. // I think ARM, p47, s5.1, forbids the use of 'this' in member // initialization. extern "C" void printf (const char*, ...); class A { public: A () {} virtual void foo () {printf ("A::foo\n");} }; class Z { public: Z (A* a) {a->foo ();} }; class B : public A { public: Z z; B () : A (), z (this) {printf ("B::B\n");} // legal?! void foo () {printf ("B::foo\n");} }; main () { B b; } // % a.out // B::foo // B::B I think the wording is poor in the section of the ARM you refer to. I think the intent is to say that "this" cannot be used except inside a member function OR a member initialization list. It is perfectly legal to call a B function from the member initialization list of B (directly or indirectly); you can initialize an integer member of B with a call to a function of B. If that function accesses members which are declared later, you lose. [ [ As an aside, this is a common and painful mistake: [ [ class Base { [ public: [ int b; [ int a; [ Base (int i) : a (i), b (a) {} // b initialized to garbage [ }; [ [ The members are initialized in the order they are declared: b, then a, [ not in the order they appear in the member initialization list. Within the body of a constructor or the member initialization list, calls to member functions of objects *more derived* cannot be made. So B's member initialization list can call B member functions, but A's member initialization list cannot call B member functions. Jak jak@cs.brown.edu ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ I never use a pen. I write with a goose quill dipped in venom. -- Waldo Lydecker, in `Laura'