Path: utzoo!utgpu!news-server.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!cs.utexas.edu!uunet!microsoft!jimad From: jimad@microsoft.UUCP (Jim ADCOCK) Newsgroups: comp.lang.c++ Subject: Re: constructor called within constructor??? Message-ID: <55661@microsoft.UUCP> Date: 5 Jul 90 17:14:40 GMT References: <965@unet.UUCP> Reply-To: jimad@microsoft.UUCP (Jim ADCOCK) Organization: Microsoft Corp., Redmond WA Lines: 54 In article <965@unet.UUCP> noemi@sugarfoot.net.com (Me) writes: >I'm trying to call a constructor routine (1) from withing another >constructor routine (2). Essentially, I want constructor 2 to do >exactly what constructor 1 does, plus one extra thing: > > public: > classname(); /* constructor 1 */ > classname(int arg); /* constructor 2 */ > > /* constructor 1 */ > classname:classname() > { > /* lots of things */ > } > > /* constructor 2 */ > classname:classname(int arg) > { > classname(); /* call constructor 1 */ > privatevar = arg; /* "one extra thing" */ > } > >Unfortunately, whatever constructor 1 does is getting lost. That is, >private variables initialized inside constructor 1 are no longer thus >after the call (at the "one extra thing" line). This is a common mistake when first exposed to C++ -- and is covered in ARM [though I can't find the page.] In C++ saying: classname(); *always* means construct a new object of type classname. If you don't specify a name for that object, you get a new anonymous object. So, when you said "classname();" in classname::classname(int arg) you just created an additional, temporary, unnamed object on the stack. Why does the language do this? -- Because in C++ constructors can also be used as conversion routines, consider: complex c1, c2; double d; ... c1 = c2 + complex(d); ^ anonymous complex constructed. How does one factor out common code in constructors? -- Following the example in ARM, one writes a helper routine, say called init(), which is then called from each constructor. If that still doesn't seem pleasing enough, consider that one can introduce an intermediate class whose constructor takes no parameters, and performs the common initialization portion of the final class's construction. Then the final derived class's constructors can take any parameters, and perform the variant portion of the construction effort.