Topic: calling constructor from contructor


Author: ebiederm@cse.unl.edu (Eric Biederman)
Date: 1995/05/04
Raw View
schuenem@informatik.tu-muenchen.de (Ulf Schuenemann) writes:


>In article <hfznepzzm53nws@themroc.colibri.de>, hf@colibri.de (Harald Fuchs) writes:
>|> clamage@Eng.Sun.COM (Steve Clamage) writes:
>|>
>|> > The way to get the effect of calling one constructor from inside another
>|> > is to factor out the common code into a private init routine, and call that
>|> > init routine from both constructors.
>|>
>|> This won't work for const members.

>.. nor for baseclasses nor for references nor for attributes without a default
>ctor -  I.e. It doesn't work for all the things that need to be constructed
>in the init-list.

>|> How about making "Foo::Foo (): Foo (0) {}" legal?

>This would be missleading, as this requires: If a ctor of the class ITSELF
>is called in the init-list of a ctor, then nothing else may be called in
>the init-list.
>Without such rule, how will the base 'Baseclass' of Foo be constructed?:

>Foo::Foo(int i)
>: Baseclass(i,i)
>{}

>Foo::Foo()
>: Baseclass(-1), Foo(0)
>{}


>How about the following - IMO less missleading (coz idifferent) - syntax:

>Foo::Foo () = Foo(0);


Well how about just using

Foo(int x = 0)

to have a constructor with variable calling schemes, It wouldn't work for
all calling schemes but it would work for most.  Another though is if you
had to have that syntax just write a wrapper class that calls the base class
constructor correctly depending on it's arguments.

--
main(c,v,n)char**v,*n;{c>1?n=v[1],c=*n++,main(c,&n-1),putchar(c):0;}







Author: schuenem@informatik.tu-muenchen.de (Ulf Schuenemann)
Date: 1995/05/03
Raw View
In article <hfznepzzm53nws@themroc.colibri.de>, hf@colibri.de (Harald Fuchs) writes:
|> clamage@Eng.Sun.COM (Steve Clamage) writes:
|>
|> > The way to get the effect of calling one constructor from inside another
|> > is to factor out the common code into a private init routine, and call that
|> > init routine from both constructors.
|>
|> This won't work for const members.

.. nor for baseclasses nor for references nor for attributes without a default
ctor -  I.e. It doesn't work for all the things that need to be constructed
in the init-list.

|> How about making "Foo::Foo (): Foo (0) {}" legal?

This would be missleading, as this requires: If a ctor of the class ITSELF
is called in the init-list of a ctor, then nothing else may be called in
the init-list.
Without such rule, how will the base 'Baseclass' of Foo be constructed?:

Foo::Foo(int i)
: Baseclass(i,i)
{}

Foo::Foo()
: Baseclass(-1), Foo(0)
{}


How about the following - IMO less missleading (coz idifferent) - syntax:

Foo::Foo () = Foo(0);


Ulf Schuenemann

--------------------------------------------------------------------
Ulf Sch   nemann
Fakult   t f   r Informatik, Technische Universit   t M   nchen, Germany.
email: schuenem@informatik.tu-muenchen.de





Author: kuehl@uzwil (Dietmar Kuehl)
Date: 1995/04/27
Raw View
Bryan Butler (bbutler@netcom.com) wrote:
: I recently created a C++ class in which a default constructor function would
: call a more general constructor function. Example:
:
: Foo::Foo()
: {
:   Foo(0);
: }
:
: Foo::Foo(int x)
: {
:   //initialize the instance of Foo
: }
:
: This seems legal to me. I couldn't find any reference to this in Stroustrup,
: but it seems to me that the constructor functions are just functions. They
: are called as a consequence of the constructing operation, with the stuff
: that happens "behing the scenes" (like allocating memory for the instance)
: occurring before the constructor function is called. In other words,
: executing:
:  new Foo;
: should cause a Foo to be allocated and Foo::Foo() to be called to initialize
: it, but executing:
:  Foo(5);
: from within an instance of Foo should initialize the current instance of Foo
: pointed to by (this).
:
: However, in stepping through my debugger (Visual C++ on WinNT 3.5) it appears
: that when the second constructor function is called, a second instance is
: created. Then, when the second constructor function returns, the destructor
: function is called, and the initialized instance is destroyed, leaving me
: with an uninitialized instance.
:
: So the question is, which of the above is correct C++?

The code is legal but does something different than you intend: In "The
C++ Programming Language", B.Stroustrup, section r.12.1 it is stated:
"A constructor can be used explicitly to create new objects of this
type, using the syntax 'class-name ( expression-list )' ... An object
created this way is unnamed (...), with its lifetime limited to the
expression in which it is created...". So you compiler is right in
creating another instance (and destroying it again).

If you want to use one common constructor to initialize your instances
you should implement a private "initialize" function which is called
from the contructors which should share the code. Another possiblity
might be to use the placement syntax of new but this might initialize
members and base classes several times (and I definitly discourage this
approach). In you example above a default argument for your second
constructor is yet another possiblity to have one constructor only.
:
: --
: -------
: Bryan Butler
: bbutler@netcom.com

dk
--
http://www.informatik.uni-konstanz.de/~kuehl/ich.html
dietmar.kuehl@uni-konstanz.de
I am a realistic optimist - that's why I appear to be slightly pessimistic





Author: hh@dialis.xs4all.nl (Henk Holterman)
Date: 1995/04/28
Raw View
Hee bbutler@netcom.com!

27 Apr 95, bbutler@netcom.com writes to All:

 bc> I recently created a C++ class in which a default constructor function
 bc> would call a more general constructor function. Example:

 bc> Foo::Foo()
 bc> {
 bc>   Foo(0);
 bc> }
 bc> Foo::Foo(int x)
 bc> {
 bc>   //initialize the instance of Foo
 bc> }

 bc> This seems legal to me.

It is legal but it doesn't do what you expect.

 bc> However, in stepping through my debugger (Visual C++ on WinNT 3.5) it
 bc> appears that when the second constructor function is called, a second
 bc> instance is created.

Exact. Constructors are *NOT* callable functions, since their name is the
same (on purpose) as that of the class using it this way is a variable
declaration.
You are creating a (nameless) temporary.

The best approach is to write (an) init-function(s) to be called from various
ctors.


-henk-    hh@dialis.xs4all.nl







Author: hf@colibri.de (Harald Fuchs)
Date: 1995/04/28
Raw View
clamage@Eng.Sun.COM (Steve Clamage) writes:

> The way to get the effect of calling one constructor from inside another
> is to factor out the common code into a private init routine, and call that
> init routine from both constructors.

This won't work for const members.
How about making "Foo::Foo (): Foo (0) {}" legal?





Author: bbutler@netcom.com (Bryan Butler)
Date: 1995/04/27
Raw View
I recently created a C++ class in which a default constructor function would
call a more general constructor function. Example:

Foo::Foo()
{
  Foo(0);
}

Foo::Foo(int x)
{
  //initialize the instance of Foo
}

This seems legal to me. I couldn't find any reference to this in Stroustrup,
but it seems to me that the constructor functions are just functions. They
are called as a consequence of the constructing operation, with the stuff
that happens "behing the scenes" (like allocating memory for the instance)
occurring before the constructor function is called. In other words,
executing:
 new Foo;
should cause a Foo to be allocated and Foo::Foo() to be called to initialize
it, but executing:
 Foo(5);
from within an instance of Foo should initialize the current instance of Foo
pointed to by (this).

However, in stepping through my debugger (Visual C++ on WinNT 3.5) it appears
that when the second constructor function is called, a second instance is
created. Then, when the second constructor function returns, the destructor
function is called, and the initialized instance is destroyed, leaving me
with an uninitialized instance.

So the question is, which of the above is correct C++?

--
-------
Bryan Butler
bbutler@netcom.com





Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1995/04/27
Raw View
In article BFC@netcom.com, bbutler@netcom.com (Bryan Butler) writes:
>I recently created a C++ class in which a default constructor function would
>call a more general constructor function. Example:
>
>Foo::Foo()
>{
>  Foo(0);
>}
>
>Foo::Foo(int x)
>{
>  //initialize the instance of Foo
>}
>
>This seems legal to me. I couldn't find any reference to this in Stroustrup,


You cannot explictly call a constructor as a function. A constructor
is implicitly invoked as part of creating an object. You can get the
effect of calling a constructor by using the "placement" form of operator new.
You almost certainly do NOT want to do that as part of the body of the
constructor for the same object, since it will reinitialize all the
base classes and members -- that is, two initializations with no
intervening destruction. This is unlikely to have any good results.

The code you wrote is legal, but doesn't do what you want. It creates
local anonymous object of type Foo, which is destroyed at the end of
Foo::Foo(). The object which ought to be constructed by Foo::Foo()
is not affected by constructing and destroying the local object.

The way to get the effect of calling one constructor from inside another
is to factor out the common code into a private init routine, and call that
init routine from both constructors.

---
Steve Clamage, stephen.clamage@eng.sun.com







Author: patil@bnr.ca (Vinayak Patilkulkarni)
Date: 1995/04/27
Raw View
In article <bbutlerD7pnv0.BFC@netcom.com>, bbutler@netcom.com (Bryan Butler) writes:
|> I recently created a C++ class in which a default constructor function would
|> call a more general constructor function. Example:
|>
|> Foo::Foo()
|> {
|>   Foo(0);
|> }
|>
It is legal. But does not work the way you want it to.
Refer to r.12.1 last paragraph in C++ programming lang. II edition.
Foo (0); is an expression whose value is not used. Calling the constructor will
create a new instance and etc etc.

|> Foo::Foo(int x)
|> {
|>   //initialize the instance of Foo
|> }
|>
|> This seems legal to me. I couldn't find any reference to this in Stroustrup,
|> but it seems to me that the constructor functions are just functions. They
|> are called as a consequence of the constructing operation, with the stuff
|> that happens "behing the scenes" (like allocating memory for the instance)
|> occurring before the constructor function is called. In other words,
|> executing:
|>  new Foo;
|> should cause a Foo to be allocated and Foo::Foo() to be called to initialize
|> it, but executing:
|>  Foo(5);
|> from within an instance of Foo should initialize the current instance of Foo
|> pointed to by (this).
|>
|> However, in stepping through my debugger (Visual C++ on WinNT 3.5) it appears
|> that when the second constructor function is called, a second instance is
|> created. Then, when the second constructor function returns, the destructor
|> function is called, and the initialized instance is destroyed, leaving me
|> with an uninitialized instance.
|>
|> So the question is, which of the above is correct C++?
|>
|> --
|> -------
|> Bryan Butler
|> bbutler@netcom.com


- Patil

# opinions are mine only.