Thread: Call constructor within constructor. How to?

  1. #1
    Registered User
    Join Date
    Jun 2004
    Posts
    722

    Call constructor within constructor. How to?

    How do i call a constructor of a class from another overloaded constructor?
    Example:
    Code:
    class Stuff{
        int a;
        Stuff(int n=0) : a(n){        
        }
        Stuff(Stuff& s) : Stuff(s.a){
        }
    };
    My compiler (MSVC++6) states that Stuff(int) is not a member of Stuff if I try to call if from Stuff(Stuff&). This example is only to show what I'm trying to ask. But I'd like possibly to call other constructors when there's a reasonable set of variables. In Java we can use the this() operator.

    I could create a initialization function to receive n arguments, being this function called by all constructors with different parameters, but that's not as efficient as calling directly the constructors for the class variables.

    So I ask is there a way of calling the constructor?

  2. #2
    Hello,

    I do know some about how constructors work, though only to this knowledge.

    Q. How can I make a constructor call another constructor as a primitive?
    A. As far as I know, you can't.
    If you call another constructor, the compiler initializes a temporary local object; it does not initialize this object. You can combine both constructors by using a default parameter, or you can share their common code in a private init() member function.

    More info here:


    Though, what you may be looking for could be different. In that case, you can learn the essentials of what can and cannot be done with overloading here: C++ Overloading.


    - Stack Overflow
    Last edited by Stack Overflow; 11-17-2004 at 05:55 PM. Reason: Link update
    Segmentation Fault: I am an error in which a running program attempts to access memory not allocated to it and core dumps with a segmentation violation error. This is often caused by improper usage of pointers, attempts to access a non-existent or read-only physical memory address, re-use of memory if freed within the same scope, de-referencing a null pointer, or (in C) inadvertently using a non-pointer variable as a pointer.

  3. #3
    Registered User
    Join Date
    Jun 2004
    Posts
    722
    Quote Originally Posted by Stack Overflow
    You can combine both constructors by using a default parameter, or you can share their common code in a private init() member function.
    Is the same as...
    I could create a initialization function to receive n arguments, being this function called by all constructors with different parameters, but that's not as efficient as calling directly the constructors for the class variables.
    Anyway, I'll just have to copy/paste chuncks of code to call variables constructors.

    But now that I'm thinking I can use a base class with inheritance
    Code:
    class base_stuff{
        /*all variables here*/
        int a;
        base_stuff() : a(0){}
    }
    class Stuff : protected base_stuff{
        Stuff(int n=0) : base_stuff(), a(n){        
        }
        Stuff(Stuff& s) : base_stuff(), a(s.a){
        }
    };
    which could simplify the constructors call.

    By the way, when calling the a() constructor from Stuff, I override the one from base_stuff right?

  4. #4
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    This
    Code:
    class Stuff{
        int a;
        Stuff(int n=0) : a(n){        
        }
        Stuff(Stuff& s) : Stuff(s.a){
        }
    };
    could be accomplished by this:
    Code:
    class Stuff{
        int a;
        Stuff(int n=0) : a(n){        
        }
        Stuff(Stuff& s) : a(s.a){
        }
    };

  5. #5
    S Sang-drax's Avatar
    Join Date
    May 2002
    Location
    Göteborg, Sweden
    Posts
    2,072
    Quote Originally Posted by xErath
    So I ask is there a way of calling the constructor?
    Yes, I can think of a somewhat ugly way to to this, using placement new:
    Code:
    class Stuff{
        int a;
        Stuff(int n=0) : a(n){        
        }
        Stuff(Stuff& s){
          new (this) Stuff (s.a);
        }
    };
    That should work, but I'm not recommending it. Perhaps some sort of initialization method would be better.

    Placement new just calls an arbitrary constructor with an extra pointer argument, which becomes the 'this'-pointer within the called constructor.
    Last edited by Sang-drax; 11-17-2004 at 06:36 PM.
    Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling

  6. #6
    Registered User
    Join Date
    Jun 2004
    Posts
    722
    Sang-drax, It isn't that ugly, but then the 2nd construdtor is called by that method, all variables are constructed, and probably they aren't de-constructed before being re-constructed. And is a "ugly" way to call a initialization function.

    jlou i know that...
    This example is only to show what I'm trying to ask. But I'd like possibly to call other constructors when there's a reasonable set of variables.
    Hum... on to the inheritance stuff then...

  7. #7
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    If you need to create an object for a class I would code a Create() function and do the init and creation in there, not in the constructor for the class.

  8. #8
    Registered User
    Join Date
    Sep 2004
    Posts
    719
    what i typically do is create and 'interface' constructor to 'parse' the parameters and then pass those values to a private member function....

    i'm not sure how efficient it is, but you can always inline private function

    ex:

    Stuff(int x=0){ BackgroundConstructor(x); }
    Stuff(Stuff &s){ BackgroundConstructor(s.a); }
    inline BackgroundConsuctor(int a){ this->myValue = a;}
    i seem to have GCC 3.3.4
    But how do i start it?
    I dont have a menu for it or anything.

  9. #9
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    Quote Originally Posted by xErath
    jlou i know that...
    This example is only to show what I'm trying to ask. But I'd like possibly to call other constructors when there's a reasonable set of variables.
    Hum... on to the inheritance stuff then...
    I knew you knew that. My badly expressed point was that I'd like you to show a better example of what you are trying to do, since I get the feeling that there might be a simpler answer.

  10. #10
    Registered User
    Join Date
    Jun 2004
    Posts
    722
    You still didn't get very well what I meant, although I apreciate your answers.
    When a class is instantiated, memory is allocated and then it is constructed. The construction works like this:
    1# if class is derived construct base class
    2# construct variables within class
    3# call class' constructor.
    To illustrate this behaviour, look at this example:
    Code:
    #include <iostream>
    class A{
    public:
    	A(){std::cout  << "A constructed\n";	}
    };
    class B{
    public:
    	B(){std::cout  << "B constructed\n";	}
    };
    class C{
    public:
    	C(){std::cout  << "C constructed\n";	}
    };
    class D: public C{
    public:
    	A a;
    	B b;
    	D(){std::cout  << "D constructed\n";	}
    };
    int main(){
    	D d;
    	return 0;
    }
    Produces the following output:
    Code:
    C constructed
    A constructed
    B constructed
    D constructed
    And if you look closely when the body of the D constructor is executed, the variables and base class have already been initialized, so calling a initialization method would be a inefficient way of doing what I sugesting, Because that would imply deconstructing the previous constructed variables, and then re-construct them, or (what would happen) making assignements with operator=, which the programmer shoudn't need to provide for every class variable within the main class scope.

    What I'm saying is: calling a constructor from another constructor to change the construction behaviour.

    But now that I see there's not much to it, my answer will be using the base class method, or copy/paste of chunks of code. Thank you for your time
    Last edited by xErath; 11-17-2004 at 08:09 PM.

  11. #11
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    It sounds like you are only trying to avoid copying the code from the initializer list. Is this true? Is it really that large of a chunk of code?

    I'd still prefer to see a real example that shows the situation. Of course, you are free to solve the problem however you want, I am just not convinced that the common solution isn't sufficient.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. minix system call pls help for project
    By porvas in forum Linux Programming
    Replies: 2
    Last Post: 06-14-2009, 02:40 AM
  2. Error C2664 - Trying to call an external Dll
    By jamez05 in forum C++ Programming
    Replies: 3
    Last Post: 08-08-2006, 06:07 AM
  3. Class won't call
    By Aalmaron in forum C++ Programming
    Replies: 3
    Last Post: 04-13-2006, 04:57 PM
  4. Iterative Tree Traversal using a stack
    By BigDaddyDrew in forum C++ Programming
    Replies: 7
    Last Post: 03-10-2003, 05:44 PM
  5. call by reference and a call by value
    By IceCold in forum C Programming
    Replies: 4
    Last Post: 09-08-2001, 05:06 PM