fail to call another constructor from constuctor

Discussion in 'C++' started by cmk128@hotmail.com, Oct 5, 2006.

  1. Guest

    hi

    1 #include <stdio.h>
    2
    3 class A{
    4 private:
    5 int x;
    6 public:
    7 A(int x){
    8 this->x;
    9 }
    10
    11 A(int x, char *y){
    12 A(x); <---------------- may
    i know how to fix this line?
    13 }
    14 };
    15
    16 int main(){
    17 return 1;
    18 }

    d.cpp: In constructor `A::A(int, char*)':
    d.cpp:12: error: declaration of `x' shadows a parameter
    d.cpp:12: error: no matching function for call to `A::A()'
    d.cpp:3: error: candidates are: A::A(const A&)
    d.cpp:11: error: A::A(int, char*)
    d.cpp:7: error: A::A(int)

    thanks
    from Peter ()
    , Oct 5, 2006
    #1
    1. Advertising

  2. laikon Guest

    just explicitly call constructor A() as follows:
    A::A(x); //line 12


    wrote:
    > hi
    >
    > 1 #include <stdio.h>
    > 2
    > 3 class A{
    > 4 private:
    > 5 int x;
    > 6 public:
    > 7 A(int x){
    > 8 this->x;
    > 9 }
    > 10
    > 11 A(int x, char *y){
    > 12 A(x); <---------------- may
    > i know how to fix this line?
    > 13 }
    > 14 };
    > 15
    > 16 int main(){
    > 17 return 1;
    > 18 }
    >
    > d.cpp: In constructor `A::A(int, char*)':
    > d.cpp:12: error: declaration of `x' shadows a parameter
    > d.cpp:12: error: no matching function for call to `A::A()'
    > d.cpp:3: error: candidates are: A::A(const A&)
    > d.cpp:11: error: A::A(int, char*)
    > d.cpp:7: error: A::A(int)
    >
    > thanks
    > from Peter ()
    laikon, Oct 5, 2006
    #2
    1. Advertising

  3. Steve Pope Guest

    laikon <> wrote:

    >just explicitly call constructor A() as follows:
    >A::A(x); //line 12


    That never works when I try it. For example, the following
    compiles with gcc but fails to print out a value of "3" --
    it prints a garbage value.

    I'm sure there's a simple explanation, but pending figuring out
    what it is, I avoid calling one constructor from another.

    Steve

    *******


    #include <iostream>

    struct A {
    int state;
    A(int x) {
    state = x;
    };
    A() {
    A::A(3);
    };
    };

    int main()
    {
    using std::cout;
    using std::endl;
    A z;
    cout << z.state << endl;
    }
    Steve Pope, Oct 5, 2006
    #3
  4. Sumit Rajan Guest

    wrote:
    > hi
    >
    > 1 #include <stdio.h>
    > 2
    > 3 class A{
    > 4 private:
    > 5 int x;
    > 6 public:
    > 7 A(int x){
    > 8 this->x;
    > 9 }
    > 10
    > 11 A(int x, char *y){
    > 12 A(x); <---------------- may
    > i know how to fix this line?
    > 13 }
    > 14 };
    > 15
    > 16 int main(){
    > 17 return 1;
    > 18 }
    >
    > d.cpp: In constructor `A::A(int, char*)':
    > d.cpp:12: error: declaration of `x' shadows a parameter
    > d.cpp:12: error: no matching function for call to `A::A()'
    > d.cpp:3: error: candidates are: A::A(const A&)
    > d.cpp:11: error: A::A(int, char*)
    > d.cpp:7: error: A::A(int)
    >
    > thanks
    > from Peter ()
    >



    See:
    http://www.parashift.com/c -faq-lite/ctors.html#faq-10.3

    Regards,
    Sumit.
    Sumit Rajan, Oct 5, 2006
    #4
  5. Zara Guest

    On 4 Oct 2006 20:47:54 -0700, wrote:

    >hi
    >
    > 1 #include <stdio.h>
    > 2
    > 3 class A{
    > 4 private:
    > 5 int x;
    > 6 public:
    > 7 A(int x){
    > 8 this->x;
    > 9 }
    > 10
    > 11 A(int x, char *y){
    > 12 A(x); <---------------- may
    >i know how to fix this line?
    > 13 }
    > 14 };
    > 15
    > 16 int main(){
    > 17 return 1;
    > 18 }
    >


    The answer is: This is not Java, and such a way to cascade
    constructors is not allowed (but it may change in the future...)


    Regards,

    Zara
    Zara, Oct 5, 2006
    #5
  6. wrote:

    > 1 #include <stdio.h>
    > 2
    > 3 class A{
    > 4 private:
    > 5 int x;
    > 6 public:
    > 7 A(int x){
    > 8 this->x;
    > 9 }
    > 10
    > 11 A(int x, char *y){
    > 12 A(x); <---------------- may
    > i know how to fix this line?
    > 13 }
    > 14 };
    > 15
    > 16 int main(){
    > 17 return 1;
    > 18 }
    >
    > d.cpp: In constructor `A::A(int, char*)':
    > d.cpp:12: error: declaration of `x' shadows a parameter
    > d.cpp:12: error: no matching function for call to `A::A()'
    > d.cpp:3: error: candidates are: A::A(const A&)
    > d.cpp:11: error: A::A(int, char*)
    > d.cpp:7: error: A::A(int)


    This is an FAQ:

    http://www.parashift.com/c -faq-lite/ctors.html#faq-10.3

    Best regards,

    Tom
    Thomas Tutone, Oct 5, 2006
    #6
  7. Kai-Uwe Bux Guest

    Steve Pope wrote:

    > laikon <> wrote:
    >
    >>just explicitly call constructor A() as follows:
    >>A::A(x); //line 12

    >
    > That never works when I try it. For example, the following
    > compiles with gcc but fails to print out a value of "3" --
    > it prints a garbage value.
    >
    > I'm sure there's a simple explanation, but pending figuring out
    > what it is, I avoid calling one constructor from another.
    >
    > Steve
    >
    > *******
    >
    >
    > #include <iostream>
    >
    > struct A {
    > int state;
    > A(int x) {
    > state = x;
    > };
    > A() {
    > A::A(3);


    This creates a temporary of type A and initializes it. Then the temporary is
    destructed. Pending side effects, this is a null op.

    > };
    > };
    >
    > int main()
    > {
    > using std::cout;
    > using std::endl;
    > A z;
    > cout << z.state << endl;
    > }


    You would need to call the constructor for the given object:


    #include <iostream>

    struct A {
    int state;
    A(int x)
    : state(x)
    {}

    A() {
    new (this) A(3);
    }
    };

    int main()
    {
    using std::cout;
    using std::endl;
    A z;
    cout << z.state << endl;
    }


    However, I it might be undefined behavior (I am not sure: 3.8/5 comes to
    mind but I am a little too lazy right now to embark on a careful exegesis
    right now).


    Best

    Kai-Uwe Bux
    Kai-Uwe Bux, Oct 5, 2006
    #7
  8. Salt_Peter Guest

    Steve Pope wrote:
    > laikon <> wrote:
    >
    > >just explicitly call constructor A() as follows:
    > >A::A(x); //line 12

    >
    > That never works when I try it. For example, the following
    > compiles with gcc but fails to print out a value of "3" --
    > it prints a garbage value.


    Constructors are not called, they are invoked. If you want the default
    state to be initialized to 3, then initialize state via the
    initialization list from within a default ctor. Calling A::A(3) simply
    creates a temporary which dies immediately.

    >
    > I'm sure there's a simple explanation, but pending figuring out
    > what it is, I avoid calling one constructor from another.


    Thats what the init list does, instead of creating and then
    initializing the state integer:
    A::A()
    {
    state = 3;
    }

    You call state's ctor directly - instantaneous allocation +
    initialization
    A::A() : state(3)
    {
    }

    >
    > Steve
    >
    > *******
    >
    >
    > #include <iostream>
    >
    > struct A {
    > int state;
    > A(int x) {
    > state = x;
    > };
    > A() {
    > A::A(3);
    > };
    > };
    >
    > int main()
    > {
    > using std::cout;
    > using std::endl;
    > A z;
    > cout << z.state << endl;
    > }


    try:

    #include <iostream>

    struct A
    {
    A() : state(3) { }
    A(int n) : state(n) { }
    int getState() const { return state; }
    private:
    int state;
    };

    int main()
    {
    A a; // invoke the default ctor
    std::cout << "a = " << a.getState() << std::endl;
    A b(101); // invoke the parametized ctor
    std::cout << "b = " << b.getState() << std::endl;
    }

    /*
    a = 3
    b = 101
    */
    Salt_Peter, Oct 5, 2006
    #8
  9. Steve Pope Guest

    Kai-Uwe Bux <> wrote:

    >Steve Pope wrote:


    >> laikon <> wrote:


    >>>just explicitly call constructor A() as follows:
    >>>A::A(x); //line 12


    >> That never works when I try it. For example, the following
    >> compiles with gcc but fails to print out a value of "3" --
    >> it prints a garbage value.


    >> I'm sure there's a simple explanation, but pending figuring out
    >> what it is, I avoid calling one constructor from another.


    >> *******
    >>
    >> #include <iostream>
    >>
    >> struct A {
    >> int state;
    >> A(int x) {
    >> state = x;
    >> };
    >> A() {
    >> A::A(3);
    >> };
    >> };
    >>
    >> int main()
    >> {
    >> using std::cout;
    >> using std::endl;
    >> A z;
    >> cout << z.state << endl;
    >> }

    >
    >This creates a temporary of type A and initializes it. Then the temporary is
    >destructed. Pending side effects, this is a null op.


    Right; if I replace A::A(3) with float(3) I get a "warning statement
    has no effect", but A::A(3) issues no warning ... as you point out
    it may have a side effect.
    >
    >You would need to call the constructor for the given object:
    >
    >#include <iostream>
    >
    >struct A {
    > int state;
    > A(int x)
    > : state(x)
    > {}
    >
    > A() {
    > new (this) A(3);
    > }
    >};
    >
    >int main()
    >{
    >using std::cout;
    >using std::endl;
    >A z;
    >cout << z.state << endl;
    >}
    >However, I it might be undefined behavior (I am not sure: 3.8/5 comes to
    >mind but I am a little too lazy right now to embark on a careful exegesis
    >right now).
    >


    Thanks Kai-Uwe. If in this situations I will separate out
    the code common to the two constructors into a member function:


    #include <iostream>

    struct A {
    int state;
    void setState(int x) { state = x; };
    A(int x) {
    setState(x);
    };
    A() {
    setState(3);
    };
    };

    int main()
    {
    using std::cout;
    using std::endl;
    A z;
    cout << z.state << endl;
    }
    Steve Pope, Oct 5, 2006
    #9
  10. Earl Purple Guest

    wrote:

    >
    > 1 #include <stdio.h>
    > 2
    > 3 class A{
    > 4 private:
    > 5 int x;
    > 6 public:
    > 7 A(int x){
    > 8 this->x;
    > 9 }
    > 10
    > 11 A(int x, char *y){
    > 12 A(x); <---------------- may
    > i know how to fix this line?
    > 13 }
    > 14 };
    > 15
    > 16 int main(){
    > 17 return 1;
    > 18 }
    >

    It's meaningless code. this->x doesn't do anything. You should say
    this->x( x ) in the initialiser but better not to call the parameter x
    at all.

    You cannot call one constructor from another but there are two
    workarounds:

    class A
    {
    private:
    void init ( int x );

    public:
    /*explicit*/ A( int x )
    {
    init( x );
    }

    A( int x, char * y )
    {
    init ( x );
    // do other stuff
    }
    };

    Then you can use private inheritance. That does allow you to call a
    constructor from a constructor - the constructor of your base class.
    You can have two of your constructors call the base class constructor.
    Because the inheritance is private, it is implementation detail of your
    class.

    class XInit
    {
    friend class A;

    XInit( int x );
    };

    class A : XInit
    {

    public:
    /*explicit*/ A( int x ) : XInit( x )
    {
    // do stuff if you want
    }

    A( int x, char * y )
    : XInit( x )
    {
    // do other stuff
    }
    };

    Here XInit is really only created for the benefit of A and it doesn't
    therefore really matter that the two are so tightly coupled. Note that
    by making A a friend of XInit and everything in it private, nothing
    else at all can use XInit, not even by deriving from it. You might
    shove it in a namespace to avoid namespace pollution.
    Earl Purple, Oct 5, 2006
    #10
  11. Ron Natalie Guest

    laikon wrote:
    > just explicitly call constructor A() as follows:
    > A::A(x); //line 12
    >


    That's not legal either.
    You can't call constructors.

    If you want to have code common to two constructors you need to
    put it in another member function that they both can call.
    Ron Natalie, Oct 5, 2006
    #11
  12. Ron Natalie Guest

    Steve Pope wrote:

    >
    > I'm sure there's a simple explanation, but pending figuring out
    > what it is, I avoid calling one constructor from another.
    >

    The simple explanation is that you can not call constructors.
    The constructors are invoked for you by the implementation as
    part of object creation. In specifiying arguments you can
    affect which overload of the constructor is used, you can not
    change the ordering or otherwise alter the process.
    Ron Natalie, Oct 5, 2006
    #12
  13. LR Guest

    Kai-Uwe Bux wrote:
    > Steve Pope wrote:
    >
    >
    >>laikon <> wrote:



    >>#include <iostream>
    >>
    >>struct A {
    >> int state;
    >> A(int x) {
    >> state = x;
    >> };
    >> A() {
    >> A::A(3);

    >
    >
    > This creates a temporary of type A and initializes it. Then the temporary is
    > destructed. Pending side effects, this is a null op.
    >
    >
    >> };
    >> };



    > You would need to call the constructor for the given object:
    >
    >
    > #include <iostream>
    >
    > struct A {
    > int state;
    > A(int x)
    > : state(x)
    > {}
    >
    > A() {
    > new (this) A(3);
    > }
    > };


    >
    > However, I it might be undefined behavior (I am not sure: 3.8/5 comes to
    > mind but I am a little too lazy right now to embark on a careful exegesis
    > right now).


    There may be other worries for other classes.

    For example, if your class inherits from a class that has a pointer
    where the default ctor allocates memory then I think new (this) might
    result in a memory leak..

    Can we make a swap member function of A?

    void A::swap(A &a) {
    std::swap(a.x,x);
    }

    and rewrite the ctor that we want to call another ctor?
    A::A()
    :
    x()
    {
    A temp(3);
    swap(temp);
    }


    LR
    LR, Oct 5, 2006
    #13
  14. Kai-Uwe Bux posted:

    > A() {
    > new (this) A(3);
    > }



    I advocate the use of:

    ::new(p)

    instead of:

    new(p)

    when using placement new. The code should be all right, just so long as no
    member objects or base-class objects have constructors which acquire
    resources or something of the like. The following is doomed to break
    because it will call "str"'s constructor twice... possible resulting in
    leaked resource, or perhaps even worse.

    #include <string>
    #include <new>

    class MyClass {
    private:

    std::string str;

    public:

    MyClass(int) {}

    MyClass(double x) { ::new(this) MyClass(x/3 +5); }
    };

    --

    Frederick Gotham
    Frederick Gotham, Oct 5, 2006
    #14
  15. Kai-Uwe Bux Guest

    Frederick Gotham wrote:

    > Kai-Uwe Bux posted:
    >
    >> A() {
    >> new (this) A(3);
    >> }

    >
    >
    > I advocate the use of:
    >
    > ::new(p)
    >
    > instead of:
    >
    > new(p)
    >
    > when using placement new. The code should be all right, just so long as no
    > member objects or base-class objects have constructors which acquire
    > resources or something of the like. The following is doomed to break
    > because it will call "str"'s constructor twice... possible resulting in
    > leaked resource, or perhaps even worse.
    >
    > #include <string>
    > #include <new>
    >
    > class MyClass {
    > private:
    >
    > std::string str;
    >
    > public:
    >
    > MyClass(int) {}
    >
    > MyClass(double x) { ::new(this) MyClass(x/3 +5); }
    >
    > };


    Correct: that would be bad. However, once you are in a state of sin, why not
    try:

    #include <string>
    #include <new>

    class MyClass {
    private:

    typedef std::string string;
    string str;

    public:

    MyClass(int) {}

    MyClass(double x) {
    (&str)->~string();
    ::new(this) MyClass(x/3 +5);
    }
    };

    Note: I am *not* advocating this.


    Best

    Kai-Uwe Bux
    Kai-Uwe Bux, Oct 5, 2006
    #15
  16. BobR Guest

    Steve Pope wrote in message ...
    >laikon <> wrote:
    >
    >>just explicitly call constructor A() as follows:
    >>A::A(x); //line 12

    >
    >That never works when I try it. For example, the following
    >compiles with gcc but fails to print out a value of "3" --
    >it prints a garbage value.
    >
    >I'm sure there's a simple explanation, but pending figuring out
    >what it is, I avoid calling one constructor from another.
    >
    >Steve
    >*******
    >
    >#include <iostream>
    >
    >struct A {
    > int state;
    > A(int x) {
    > state = x;
    > };
    > A() {
    > A::A(3);
    > };
    > };
    >
    >int main(){
    >using std::cout;
    >using std::endl;
    >A z;
    >cout << z.state << endl;
    >}


    Hmmm, maybe you just want a default value?

    struct A {
    int state;
    A( int x = 3 ) : state( x ) {};
    };

    int main(){
    using std::cout;
    using std::endl;
    A z;
    cout << z.state << endl;
    A y(23);
    cout << y.state << endl;
    }

    // -- output --
    3
    23

    --
    Bob R
    POVrookie
    BobR, Oct 5, 2006
    #16
  17. Kai-Uwe Bux posted:

    > MyClass(double x) {
    > (&str)->~string();
    > ::new(this) MyClass(x/3 +5);
    > }



    Now all we need is a compiler that optimises-away a construction followed
    immediately by a destruction ; ).


    --

    Frederick Gotham
    Frederick Gotham, Oct 5, 2006
    #17
  18. LR Guest

    LR, Oct 5, 2006
    #18
  19. Steve Pope Guest

    BobR <> replies to my post,

    >Hmmm, maybe you just want a default value?
    >
    >struct A {
    > int state;
    > A( int x = 3 ) : state( x ) {};
    > };


    Thanks, that certainly works.

    Steve
    Steve Pope, Oct 5, 2006
    #19
    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. Alexander Stippler
    Replies:
    3
    Views:
    431
    Leor Zolman
    Apr 9, 2004
  2. Tapeesh

    Default constuctor

    Tapeesh, Mar 1, 2005, in forum: C++
    Replies:
    4
    Views:
    454
    John Carson
    Mar 2, 2005
  3. Generic Usenet Account
    Replies:
    10
    Views:
    2,205
  4. Sid K
    Replies:
    2
    Views:
    256
    Sid K
    Aug 7, 2008
  5. Unknown Poster

    still crabby about copy constuctor craziness

    Unknown Poster, Jul 24, 2004, in forum: Perl Misc
    Replies:
    16
    Views:
    193
    Ilya Zakharevich
    Aug 2, 2004
Loading...

Share This Page