Thread: Specialized Constructor call Default Constructor

  1. #1
    template<typename T> threahdead's Avatar
    Join Date
    Sep 2002
    Posts
    214

    Specialized Constructor call Default Constructor

    Hey ppl,

    i have a class similar to this one

    Code:
    class Foo
    {
    public:
        Foo(void) : m1(0) {};
        Foo(int a) : Foo(), a(a) {};
        ~Foo(void) {};
    
    private:
        int m1;
        int a;
    };
    Which does give me a "illegal member initialization, Foo is not a base or member". What i want to do actually, is to have the specialized constructor Foo(int a), call Foo(void) for common initializations and then have its special variable initialized.

    How can i get this to work with initializations lists?

    Best regard, threahdead

  2. #2
    Anti-Poster
    Join Date
    Feb 2002
    Posts
    1,401
    C++ doesn't allow nested constructors. Notice that you should probably initialize a to some value anyway, so you might be able to use a constructor with default parameters:
    Code:
    Foo(int a = 0) : a(a), m1(0) { }
    If I did your homework for you, then you might pass your class without learning how to write a program like this. Then you might graduate and get your degree without learning how to write a program like this. You might become a professional programmer without knowing how to write a program like this. Someday you might work on a project with me without knowing how to write a program like this. Then I would have to do you serious bodily harm. - Jack Klein

  3. #3
    The larch
    Join Date
    May 2006
    Posts
    3,573
    This will be only possible in C++0x, which adds "delegating constructors" to the language.

    Currently, one overload of a constructor cannot reuse a different constructor of the same class.

    -------

    BTW, even in C++0x I doubt that you will be allowed to initialize the same member twice (although technically the default constructor just leaves one member uninitialized).

    A quote from the draft for C++0x:

    6 A mem-initializer-list can delegate to another constructor of the constructor’s class using any class-ordecltype
    that denotes the constructor’s class itself. If a mem-initializer-id designates the constructor’s class,
    it shall be the only mem-initializer
    ; the constructor is a delegating constructor, and the constructor selected
    by the mem-initializer is the target constructor. The principal constructor is the first constructor invoked
    in the construction of an object (that is, not a target constructor for that object’s construction). The
    target constructor is selected by overload resolution. Once the target constructor returns, the body of the
    delegating constructor is executed. If a constructor delegates to itself directly or indirectly, the program is
    ill-formed; no diagnostic is required. [ Example:
    Code:
    struct C {
      C( int ) { } // #1: non-delegating constructor
      C(): C(42) { } // #2: delegates to #1
      C( char c ) : C(42.0) { } // #3: ill-formed due to recursion with #4
      C( double d ) : C(’a’) { } // #4: ill-formed due to recursion with #3
    };
    —end example ]
    The emphasised part says that you will never be able to do exactly what you are asking.
    Last edited by anon; 08-18-2010 at 10:38 AM.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  4. #4
    template<typename T> threahdead's Avatar
    Join Date
    Sep 2002
    Posts
    214
    Thanks for replies. Sadly, in my case default values in the constructor are not an option.

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Why not?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by threahdead View Post
    Thanks for replies. Sadly, in my case default values in the constructor are not an option.
    As laserlight asked, why not?

    Your example seems rather silly - in fact, dangerous - because the member a is not actually initialised by the default constructor, but it is for an object constructed from an int - with no way for an object to detect the difference. Any member that retrieves the value of an uninitialised "a" will give undefined behaviour.

    The solution to use common code in constructors - assuming that is OK from the constructor body - is typically to have a private initialiser function, and call it from each constructor.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  7. #7
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    BTW, why do people keep calling it 'C++0x'? Shouldn't it be C++1x now? Unless they plan on waiting another 90 years to release it?
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by cpjust
    BTW, why do people keep calling it 'C++0x'? Shouldn't it be C++1x now?
    The next version of the C++ standard is currently scheduled to be C++0B
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Because that's how my compiler calls it, it doesn't accept "-std=c++1x".
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  10. #10
    template<typename T> threahdead's Avatar
    Join Date
    Sep 2002
    Posts
    214
    Quote Originally Posted by grumpy View Post
    As laserlight asked, why not?

    Your example seems rather silly - in fact, dangerous - because the member a is not actually initialised by the default constructor, but it is for an object constructed from an int - with no way for an object to detect the difference. Any member that retrieves the value of an uninitialised "a" will give undefined behaviour.

    The solution to use common code in constructors - assuming that is OK from the constructor body - is typically to have a private initialiser function, and call it from each constructor.
    You are absolutely correct about my example. In my code, which i was too lazy to type in here, it is a little bit different. Let me give you a better example.
    I have a whole bunch of variables which are initialized to the same values in all specialized constructors and only one or two which are initialized to special values in each constructor respectively.

    Code:
    class Foo
    {
    public:
        Foo(A a) : m1(0), m2(0), m3(0), a(a), b(NULL) {};
        Foo(B b) : m1(0), m2(0), m3(0), b(b), a(NULL) {};
    
        ~Foo() {};
    
    private:
        int m1, m2, m3;
        A a;
        B b;
    };
    What i want to do is still the same, have a constructor with no arguments that initializes m1, m2 and m3 which can be called from the initialization list in each of the specialized constructors.

    Code:
    Foo(void) : m1(0), m2(0), m3(0) {};
    Foo(A a) : Foo(), a(a), b(NULL) {};
    Which would be much cleaner code.

    Best regards, threahdead

  11. #11
    Registered User
    Join Date
    Aug 2003
    Posts
    1,218
    Well one workaround would be to use inheritance to do that. You can call the base-class constructor which would initialize the m variables, and then let the inherited class take care of the specialized constructors. It is the only way you can do what you want that i know of.

  12. #12
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    I understand that's what you want to do. If your compiler complies with the original C++ standard, you can't. In future you will be able to do that with delegating constructors (assuming that feature is ratified, which seems likely).

    You might try putting the m1, m2, m3 members into a helper class (or struct) that has a default constructor to initialise them. It's not as clean as you might like, but does allow reuse of the initialisation logic.

    Also, for readability sake, it's often considered a good idea to avoid giving arguments of constructors the same name as a member of the class. Having a(a) in an initialiser list is an easy way to confuse yourself - or some poor sucker maintaining your code in future.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  13. #13
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by grumpy View Post
    I understand that's what you want to do. If your compiler complies with the original C++ standard, you can't. In future you will be able to do that with delegating constructors (assuming that feature is ratified, which seems likely).
    Or using default initializers in the class definition! Handy stuff!
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  14. #14
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by Elysia View Post
    Or using default initializers in the class definition! Handy stuff!
    Yeah, but that's not what was asked for.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  15. #15
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    That is exactly what was asked for:
    Quote Originally Posted by threahdead View Post
    I have a whole bunch of variables which are initialized to the same values in all specialized constructors and only one or two which are initialized to special values in each constructor respectively.
    So, in other words, default initialize all of the variables in the class body, and have the constructors initialize the specific variables to specific values.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. default constructor
    By rahulsk1947 in forum C++ Programming
    Replies: 1
    Last Post: 06-10-2009, 12:52 PM
  2. Creating array of objects w/o default constructor
    By QuestionC in forum C++ Programming
    Replies: 19
    Last Post: 05-02-2007, 08:03 PM
  3. template class default constructor problem
    By kocika73 in forum C++ Programming
    Replies: 3
    Last Post: 04-22-2006, 09:42 PM
  4. constructors
    By shrivk in forum C++ Programming
    Replies: 7
    Last Post: 06-24-2005, 09:35 PM
  5. Need help in classes
    By LBY in forum C++ Programming
    Replies: 11
    Last Post: 11-26-2004, 04:50 AM