Constructors that call other Constructors

Discussion in 'C++' started by Dave Rudolf, Feb 5, 2004.

  1. Dave Rudolf

    Dave Rudolf Guest

    Hi all,

    At the risk of mentioning Java in a C++ news group :), I'm curious if there
    is a way to reuse constructors in C++ similar to what can be done in Java.
    For instance, in java, I can do the following:

    public class Rectangle
    {
    public Rectangle( int width, int height )
    {
    // Do stuff here
    }

    public Rectangle( int widthAndHeight )
    {
    this( widthAndHeight , widthAndHeight );
    }
    }

    That is, the second constructor simply calls the first to do all of the
    dirty work. Is there some similar concept in C++? Certainly, a direct
    translation does not work.

    Dave
     
    Dave Rudolf, Feb 5, 2004
    #1
    1. Advertising

  2. On Wed, 4 Feb 2004 20:38:16 -0600, "Dave Rudolf" <> wrote:

    >At the risk of mentioning Java in a C++ news group :), I'm curious if there
    >is a way to reuse constructors in C++ similar to what can be done in Java.
    >For instance, in java, I can do the following:
    >
    >public class Rectangle
    >{
    > public Rectangle( int width, int height )
    > {
    > // Do stuff here
    > }
    >
    > public Rectangle( int widthAndHeight )
    > {
    > this( widthAndHeight , widthAndHeight );
    > }
    >}
    >
    >That is, the second constructor simply calls the first to do all of the
    >dirty work. Is there some similar concept in C++? Certainly, a direct
    >translation does not work.


    In C++ use a non-virtual member function e.g. called 'init'. Call that
    from each constructor. You cannot do that safely in Java since all
    methods in Java are virtual, so Java needs the "constructor reuse"; it's
    not needed and therefore not supported in C++.

    By the way, this is a FAQ,
    <url: http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.3>.

    You should always check the FAQ first before asking here.
     
    Alf P. Steinbach, Feb 5, 2004
    #2
    1. Advertising

  3. Dave Rudolf

    Dan Cernat Guest

    "Dave Rudolf" <> wrote in message
    news:...
    > Hi all,
    >
    > At the risk of mentioning Java in a C++ news group :), I'm curious if

    there
    > is a way to reuse constructors in C++ similar to what can be done in Java.
    > For instance, in java, I can do the following:
    >
    > public class Rectangle
    > {
    > public Rectangle( int width, int height )
    > {
    > // Do stuff here
    > }
    >
    > public Rectangle( int widthAndHeight )
    > {
    > this( widthAndHeight , widthAndHeight );
    > }
    > }
    >
    > That is, the second constructor simply calls the first to do all of the
    > dirty work. Is there some similar concept in C++? Certainly, a direct
    > translation does not work.
    >
    > Dave
    >


    no, one cannot use constructors like you mentioned.
    however, there are two solutions to your problem
    1. use a common function
    class Rectangle
    {
    private:
    void DoStuff(int w, int h)
    {
    // do the stuff here
    }
    public:
    Rectangle ( int width_and_height)
    {
    DoStuff(width_and_height, width_and_height);
    }
    Rectangle ( int w, int h)
    {
    DoStuff(w, h);
    }
    };

    2. use default values
    class Rectangle
    {
    public:
    Rectangle ( int w, int h = GetTheDefaultheightValue())
    {
    // do stuff with w and h
    }

    private:
    int GetTheDefaultheightValue()
    {
    rturn 42;
    }
    };

    dan
     
    Dan Cernat, Feb 5, 2004
    #3
  4. "Dave Rudolf" <> wrote in message
    news:...
    > Hi all,
    >
    > At the risk of mentioning Java in a C++ news group :), I'm curious

    if there
    > is a way to reuse constructors in C++ similar to what can be done in

    Java.
    > For instance, in java, I can do the following:
    >
    > public class Rectangle
    > {
    > public Rectangle( int width, int height )
    > {
    > // Do stuff here
    > }
    >
    > public Rectangle( int widthAndHeight )
    > {
    > this( widthAndHeight , widthAndHeight );
    > }
    > }
    >
    > That is, the second constructor simply calls the first to do all of

    the
    > dirty work. Is there some similar concept in C++? Certainly, a

    direct
    > translation does not work.
    >


    There has been discussion of adding a mechanism like this to C++,
    using the syntax for base initialization:

    Rectangle(int widthAndHeight) : Rectangle(widthAndHeight ,
    widthAndHeight ) { }

    See http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1395.txt.

    In your example you could possibly do something like this:

    Rectangle(int width, int height = -1)
    : width_(width),
    height_(height != -1 ? height : width)
    { }

    (By the way, in C++ you might want to start thinking along these
    lines:

    Rectangle( int width, int height )
    // Do stuff here
    {
    // Do stuff here
    } )

    Jonathan
     
    Jonathan Turkanis, Feb 5, 2004
    #4
  5. "Dan Cernat" <> skrev i en meddelelse
    news:...
    >
    > "Dave Rudolf" <> wrote in message
    > news:...
    > > Hi all,
    > >
    > > At the risk of mentioning Java in a C++ news group :), I'm curious if

    > there
    > > is a way to reuse constructors in C++ similar to what can be done in

    Java.
    > > For instance, in java, I can do the following:
    > >
    > > public class Rectangle
    > > {
    > > public Rectangle( int width, int height )
    > > {
    > > // Do stuff here
    > > }
    > >
    > > public Rectangle( int widthAndHeight )
    > > {
    > > this( widthAndHeight , widthAndHeight );
    > > }
    > > }
    > >
    > > That is, the second constructor simply calls the first to do all of the
    > > dirty work. Is there some similar concept in C++? Certainly, a direct
    > > translation does not work.
    > >
    > > Dave
    > >

    >
    > no, one cannot use constructors like you mentioned.
    > however, there are two solutions to your problem
    > 1. use a common function
    > class Rectangle
    > {
    > private:
    > void DoStuff(int w, int h)
    > {
    > // do the stuff here
    > }
    > public:
    > Rectangle ( int width_and_height)
    > {
    > DoStuff(width_and_height, width_and_height);
    > }
    > Rectangle ( int w, int h)
    > {
    > DoStuff(w, h);
    > }
    > };
    >
    > 2. use default values
    > class Rectangle
    > {
    > public:
    > Rectangle ( int w, int h = GetTheDefaultheightValue())
    > {
    > // do stuff with w and h
    > }
    >
    > private:
    > int GetTheDefaultheightValue()
    > {
    > rturn 42;
    > }
    > };
    >
    > dan
    >


    Well.... that second version is a little suspect, isn't it? calling a
    memberfunction on a noninitialized object.
     
    Peter Koch Larsen, Feb 5, 2004
    #5
  6. "Peter Koch Larsen" <> wrote...
    >
    > "Dan Cernat" <> skrev i en meddelelse
    > news:...
    > > 2. use default values
    > > class Rectangle
    > > {
    > > public:
    > > Rectangle ( int w, int h = GetTheDefaultheightValue())
    > > {
    > > // do stuff with w and h
    > > }
    > >
    > > private:
    > > int GetTheDefaultheightValue()
    > > {
    > > rturn 42;
    > > }
    > > };
    > >
    > > dan
    > >

    >
    > Well.... that second version is a little suspect, isn't it? calling a
    > memberfunction on a noninitialized object.


    What's noninitialized about 42?
     
    Victor Bazarov, Feb 5, 2004
    #6
  7. Dave Rudolf

    Dan Cernat Guest

    "Peter Koch Larsen" <> wrote in message
    news:fotUb.85255$...
    >
    > "Dan Cernat" <> skrev i en meddelelse
    > news:...
    > >
    > > "Dave Rudolf" <> wrote in message
    > > news:...
    > > > Hi all,
    > > >
    > > > At the risk of mentioning Java in a C++ news group :), I'm curious if

    > > there
    > > > is a way to reuse constructors in C++ similar to what can be done in

    > Java.
    > > > For instance, in java, I can do the following:
    > > >
    > > > public class Rectangle
    > > > {
    > > > public Rectangle( int width, int height )
    > > > {
    > > > // Do stuff here
    > > > }
    > > >
    > > > public Rectangle( int widthAndHeight )
    > > > {
    > > > this( widthAndHeight , widthAndHeight );
    > > > }
    > > > }
    > > >
    > > > That is, the second constructor simply calls the first to do all of

    the
    > > > dirty work. Is there some similar concept in C++? Certainly, a direct
    > > > translation does not work.
    > > >
    > > > Dave
    > > >

    > >
    > > no, one cannot use constructors like you mentioned.
    > > however, there are two solutions to your problem
    > > 1. use a common function
    > > class Rectangle
    > > {
    > > private:
    > > void DoStuff(int w, int h)
    > > {
    > > // do the stuff here
    > > }
    > > public:
    > > Rectangle ( int width_and_height)
    > > {
    > > DoStuff(width_and_height, width_and_height);
    > > }
    > > Rectangle ( int w, int h)
    > > {
    > > DoStuff(w, h);
    > > }
    > > };
    > >
    > > 2. use default values
    > > class Rectangle
    > > {
    > > public:
    > > Rectangle ( int w, int h = GetTheDefaultheightValue())
    > > {
    > > // do stuff with w and h
    > > }
    > >
    > > private:
    > > int GetTheDefaultheightValue()
    > > {
    > > rturn 42;
    > > }
    > > };
    > >
    > > dan
    > >

    >
    > Well.... that second version is a little suspect, isn't it? calling a
    > memberfunction on a noninitialized object.
    >
    >


    Hmmm, yes, you are right if GetTheDefaultheightValue() tries to use any
    members of the object that is in process of constructing at that moment. I
    used that example to emphasis the fact that the default arguments aren't
    necessarely constants, but can be the result of a function call, as well.

    dan
     
    Dan Cernat, Feb 5, 2004
    #7
  8. "Victor Bazarov" <> skrev i en meddelelse
    news:WguUb.98813$U%5.488957@attbi_s03...
    > "Peter Koch Larsen" <> wrote...
    > >
    > > "Dan Cernat" <> skrev i en meddelelse
    > > news:...
    > > > 2. use default values
    > > > class Rectangle
    > > > {
    > > > public:
    > > > Rectangle ( int w, int h = GetTheDefaultheightValue())
    > > > {
    > > > // do stuff with w and h
    > > > }
    > > >
    > > > private:
    > > > int GetTheDefaultheightValue()
    > > > {
    > > > rturn 42;
    > > > }
    > > > };
    > > >
    > > > dan
    > > >

    > >
    > > Well.... that second version is a little suspect, isn't it? calling a
    > > memberfunction on a noninitialized object.

    >
    > What's noninitialized about 42?
    >


    Nothing. But look what I wrote. Even though the above construct looks quite
    innocent and probably works on actual implementations, my guess is that it
    is undefined behaviour if allowed at all.

    Kind regards
    Peter
     
    Peter Koch Larsen, Feb 5, 2004
    #8
  9. "Peter Koch Larsen" <> wrote...
    >
    > "Victor Bazarov" <> skrev i en meddelelse
    > news:WguUb.98813$U%5.488957@attbi_s03...
    > > "Peter Koch Larsen" <> wrote...
    > > >
    > > > "Dan Cernat" <> skrev i en meddelelse
    > > > news:...
    > > > > 2. use default values
    > > > > class Rectangle
    > > > > {
    > > > > public:
    > > > > Rectangle ( int w, int h = GetTheDefaultheightValue())
    > > > > {
    > > > > // do stuff with w and h
    > > > > }
    > > > >
    > > > > private:
    > > > > int GetTheDefaultheightValue()
    > > > > {
    > > > > rturn 42;
    > > > > }
    > > > > };
    > > > >
    > > > > dan
    > > > >
    > > >
    > > > Well.... that second version is a little suspect, isn't it? calling a
    > > > memberfunction on a noninitialized object.

    > >
    > > What's noninitialized about 42?
    > >

    >
    > Nothing. But look what I wrote. Even though the above construct looks

    quite
    > innocent and probably works on actual implementations, my guess is that it
    > is undefined behaviour if allowed at all.


    In this particular case, calling a _non_static_ member function is simply
    not allowed, you're correct. But if we take our discussion into academics,
    why do you say that it would be _undefined_behaviour_?

    V
     
    Victor Bazarov, Feb 5, 2004
    #9
  10. Dave Rudolf

    Dave Rudolf Guest

    > (By the way, in C++ you might want to start thinking along these
    > lines:
    >
    > Rectangle( int width, int height )
    > // Do stuff here
    > {
    > // Do stuff here
    > } )
    >
    > Jonathan
    >
    >


    Yes, I generally use initialization lists outside of the "code block". The
    only exception is when the initialization requires some number crunching.
    But I do this because I have been told that it is the right way to write
    C++, although you have me curious as to why this is the preferred way to
    initialize local fields. Is it an optimization thing ?

    Dave
     
    Dave Rudolf, Feb 6, 2004
    #10
  11. "Dave Rudolf" <> wrote...
    > > (By the way, in C++ you might want to start thinking along these
    > > lines:
    > >
    > > Rectangle( int width, int height )
    > > // Do stuff here
    > > {
    > > // Do stuff here
    > > } )
    > >
    > > Jonathan
    > >
    > >

    >
    > Yes, I generally use initialization lists outside of the "code block". The
    > only exception is when the initialization requires some number crunching.
    > But I do this because I have been told that it is the right way to write
    > C++, although you have me curious as to why this is the preferred way to
    > initialize local fields. Is it an optimization thing ?


    It's covered in the FAQ. See 'Constructors'.

    V
     
    Victor Bazarov, Feb 6, 2004
    #11
  12. "Dave Rudolf" <> wrote in message
    news:...

    >
    > Yes, I generally use initialization lists outside of the "code

    block". The
    > only exception is when the initialization requires some number

    crunching.
    > But I do this because I have been told that it is the right way to

    write
    > C++, although you have me curious as to why this is the preferred

    way to
    > initialize local fields. Is it an optimization thing ?
    >


    By the time you get to rthe body of the constructors, bases and
    members have already been initialized. Sometime you are forced to
    initialize a base or member explicitly in the initializer list, .e.g.
    for const or reference members or types without default constructors
    or assignment operators. Even when a type has a default constructor
    and assignment operator, default initialization + assignment may not
    have the same semantics as direct initialization, and is often less
    efficient.

    Jonathan
     
    Jonathan Turkanis, Feb 6, 2004
    #12
  13. On Wed, 04 Feb 2004 20:38:16 -0600, Dave Rudolf wrote:

    > Hi all,
    >
    > At the risk of mentioning Java in a C++ news group :), I'm curious if there
    > is a way to reuse constructors in C++ similar to what can be done in Java.
    > For instance, in java, I can do the following:
    >
    > public class Rectangle
    > {
    > public Rectangle( int width, int height )
    > {
    > // Do stuff here
    > }
    >
    > public Rectangle( int widthAndHeight )
    > {
    > this( widthAndHeight , widthAndHeight );
    > }
    > }
    >
    > That is, the second constructor simply calls the first to do all of the
    > dirty work. Is there some similar concept in C++? Certainly, a direct
    > translation does not work.


    Another technique is to factor out the common behaviour in a base class.
    This may seem overkill at first, but in reality is surprisingly often
    only an implementation of one-class, one-responsibility.

    HTH,
    M4
     
    Martijn Lievaart, Feb 6, 2004
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jeremy Smith
    Replies:
    2
    Views:
    590
    Jeremy Smith
    Aug 3, 2006
  2. Jess
    Replies:
    5
    Views:
    609
    Ron Natalie
    Jun 7, 2007
  3. Peng Yu
    Replies:
    5
    Views:
    399
    Juha Nieminen
    Sep 19, 2008
  4. srp113
    Replies:
    3
    Views:
    470
  5. laredotornado
    Replies:
    7
    Views:
    1,355
    Eric Sosman
    Dec 4, 2009
Loading...

Share This Page