Why is the Constructor called 4 times but the Destructor 5 times?

Discussion in 'C++' started by djskrill, Sep 30, 2003.

  1. djskrill

    djskrill Guest

    Why is the Constructor called 4 times but the Destructor 5 times? I am
    using MS VC 6. If this has been covered already please let me know.

    The Code:

    #include <stdio.h>

    class MyClass {
    private:
    int x;
    int y;
    static int count;
    int id;
    public:
    MyClass(int x=0,int y=0): x(x),y(y){
    printf("Create (%d)\n",++count);
    id = count;
    }
    ~MyClass(){
    printf("kill (%d)\n",id);
    }
    MyClass(const MyClass &r){
    printf("Copy\n");
    x = r.x;
    y = r.y;
    }

    void Set(int ix,int iy){
    x = ix; y = iy;
    }
    void Print(){
    printf("x=%d y=%d\n",x,y);
    }

    //operators
    MyClass operator + (const MyClass &left){
    printf("Start +\n");
    MyClass temp;
    temp.x = x + left.x; temp.y = y + left.y;
    printf("End +\n");
    return temp;
    }
    MyClass &operator += (const MyClass &left){
    x += left.x; y += left.y;
    return *this;
    }
    MyClass &operator += (int left){
    x += left; y += left;
    return *this;
    }
    MyClass &operator = (const MyClass &r){
    x = r.x; y = r.y;
    return *this;
    }
    };

    int MyClass::count = 0;

    int main(int argc,char **argv){

    MyClass c1(5,6);
    MyClass c2(1,1);
    MyClass c3(100,200);



    printf("before\n");
    c1.Print();
    c2.Print();
    c3.Print();

    c3 = c1+ c2;

    printf("after\n");
    c1.Print();
    c2.Print();
    c3.Print();


    return 0;
    }
    djskrill, Sep 30, 2003
    #1
    1. Advertising

  2. djskrill

    Ron Natalie Guest

    "djskrill" <> wrote in message news:...
    > Why is the Constructor called 4 times but the Destructor 5 times? I am
    > using MS VC 6. If this has been covered already please let me know.


    A constructor is called 5 times. After modifying your copy constructor to actually
    initialize the id field:

    MyClass& operator=(const MyClass& r) {
    id = r. id;
    x = r.x;
    y = r.y;
    }

    This is what I get as output: (annoated)
    Create (1) // main c1 variable
    Create (2) // main c2 variable
    Create (3) // main c3 variable
    before
    x=5 y=6
    x=1 y=1
    x=100 y=200
    Start +
    Create (4) // operator+ temp
    End +
    Copy (5) // return value temporary
    kill (4)
    kill (5)
    after
    x=5 y=6
    x=1 y=1
    x=6 y=7
    kill (3)
    kill (2)
    kill (1)


    Which
    Ron Natalie, Sep 30, 2003
    #2
    1. Advertising

  3. djskrill

    Mike Wahler Guest

    "djskrill" <> wrote in message
    news:...
    > Why is the Constructor called 4 times but the Destructor 5 times? I am
    > using MS VC 6. If this has been covered already please let me know.
    >
    > The Code:


    Please indent your code. It's not very readable without it.
    >
    > #include <stdio.h>


    Why aren't you using iostreams?

    >
    > class MyClass {
    > private:
    > int x;
    > int y;
    > static int count;
    > int id;
    > public:
    > MyClass(int x=0,int y=0): x(x),y(y){
    > printf("Create (%d)\n",++count);
    > id = count;
    > }
    > ~MyClass(){
    > printf("kill (%d)\n",id);
    > }



    > MyClass(const MyClass &r){


    This is a constructor. A 'copy constructor'.

    > printf("Copy\n");
    > x = r.x;
    > y = r.y;


    You've left 'count' uninitialized.
    Evalutating its value will give undefined behavior.

    > }


    Also, why aren't you using initializer list?

    MyClass(const MyClass &r) : x(r.x), y(r.y), count(r.count)
    {
    printf("Copy\n");
    }

    More below.

    >
    > void Set(int ix,int iy){
    > x = ix; y = iy;
    > }
    > void Print(){
    > printf("x=%d y=%d\n",x,y);
    > }
    >
    > //operators
    > MyClass operator + (const MyClass &left){
    > printf("Start +\n");
    > MyClass temp;
    > temp.x = x + left.x; temp.y = y + left.y;
    > printf("End +\n");
    > return temp;
    > }
    > MyClass &operator += (const MyClass &left){
    > x += left.x; y += left.y;
    > return *this;
    > }
    > MyClass &operator += (int left){
    > x += left; y += left;
    > return *this;
    > }
    > MyClass &operator = (const MyClass &r){
    > x = r.x; y = r.y;
    > return *this;
    > }
    > };
    >
    > int MyClass::count = 0;
    >
    > int main(int argc,char **argv){
    >
    > MyClass c1(5,6);
    > MyClass c2(1,1);
    > MyClass c3(100,200);
    >
    >
    >
    > printf("before\n");
    > c1.Print();
    > c2.Print();
    > c3.Print();
    >
    > c3 = c1+ c2;
    >
    > printf("after\n");
    > c1.Print();
    > c2.Print();
    > c3.Print();
    >
    >
    > return 0;
    > }


    I get output with VC++6.0 SP5:

    Create (1)
    Create (2)
    Create (3)
    before
    x=5 y=6
    x=1 y=1
    x=100 y=200
    Start +
    Create (4)
    End +
    Copy <<== note that this is a ctor call
    kill (4)
    kill (-858993460) <<== this alerted me to the 'uninitialized' problem
    after
    x=5 y=6
    x=1 y=1
    x=6 y=7
    kill (3)
    kill (2)
    kill (1)


    I see five ctor calls, and five dtor calls.

    -Mike
    Mike Wahler, Sep 30, 2003
    #3
  4. djskrill

    Mike Wahler Guest

    Re: (corr) Why is the Constructor called 4 times but the Destructor 5 times?

    "Mike Wahler" <> wrote in message
    news:%Vkeb.9124$...

    > > MyClass(const MyClass &r){

    >
    > This is a constructor. A 'copy constructor'.
    >


    After reading Ron's reply, I realized I have erred.

    > > printf("Copy\n");
    > > x = r.x;
    > > y = r.y;

    >
    > You've left 'count' uninitialized.


    'id'


    > Evalutating its value will give undefined behavior.
    >
    > > }

    >
    > Also, why aren't you using initializer list?
    >
    > MyClass(const MyClass &r) : x(r.x), y(r.y), count(r.count)


    MyClass(const MyClass &r) : x(r.x), y(r.y), id(r.id)


    Sorry about that. That's what I get for not compiling and
    testing my corrections. :)

    -Mike
    Mike Wahler, Sep 30, 2003
    #4
  5. djskrill

    Ron Natalie Guest

    "Mike Wahler" <> wrote in message news:%Vkeb.9124$...

    > Please indent your code. It's not very readable without it.


    His code is indented. It's just that your news reader (presumably outlook express)
    is eating the tabs on display.


    >
    > You've left 'count' uninitialized.
    > Evalutating its value will give undefined behavior.


    Actually, he left id uninitialized. Count is a static.
    Ron Natalie, Sep 30, 2003
    #5
  6. djskrill

    Ron Natalie Guest

    Re: (corr) Why is the Constructor called 4 times but the Destructor 5 times?

    "Mike Wahler" <> wrote in message news:2Zkeb.9127$...

    >
    > MyClass(const MyClass &r) : x(r.x), y(r.y), id(r.id)
    >
    >
    > Sorry about that. That's what I get for not compiling and
    > testing my corrections. :)
    >

    Actually, he doesn't want to copy the id. He wants to give it
    a new serial number, otherwise it's impossible to pair up the destructors.
    Ron Natalie, Sep 30, 2003
    #6
  7. djskrill

    Mike Wahler Guest

    Re: (corr) Why is the Constructor called 4 times but the Destructor 5 times?

    "Ron Natalie" <> wrote in message
    news:3f79e497$0$36960$...
    >
    > "Mike Wahler" <> wrote in message

    news:2Zkeb.9127$...
    >
    > >
    > > MyClass(const MyClass &r) : x(r.x), y(r.y), id(r.id)
    > >
    > >
    > > Sorry about that. That's what I get for not compiling and
    > > testing my corrections. :)
    > >

    > Actually, he doesn't want to copy the id. He wants to give it
    > a new serial number, otherwise it's impossible to pair up the destructors.


    Oh, yes, overlooked that.

    -Mike
    Mike Wahler, Sep 30, 2003
    #7
  8. "Mike Wahler" <> wrote in message news:<%Vkeb.9124$>...
    [snip]
    > > MyClass(const MyClass &r){

    >
    > This is a constructor. A 'copy constructor'.
    >
    > > printf("Copy\n");
    > > x = r.x;
    > > y = r.y;

    >
    > You've left 'count' uninitialized.
    > Evalutating its value will give undefined behavior.
    >
    > > }

    >
    > Also, why aren't you using initializer list?
    >
    > MyClass(const MyClass &r) : x(r.x), y(r.y), count(r.count)
    > {
    > printf("Copy\n");
    > }
    >

    but count is static and need not be initialized in constructors. I
    believe you meant id. But then again, the proper way would be:

    MyClass(const MyClass &r) : x(r.x), y(r.y)
    {
    ++count;
    id = count;
    printf("Copy create (%d)\n",++count);
    }

    which would correct two problems: the garbage you get when printing id
    at destruction time, and accounting for the construction of the
    object.

    Regards,

    Marcelo Pinto
    Marcelo Pinto, Oct 1, 2003
    #8
  9. (Marcelo Pinto) wrote in message news:<>...
    > "Mike Wahler" <> wrote in message news:<%Vkeb.9124$>...

    [snip]
    > but count is static and need not be initialized in constructors. I
    > believe you meant id. But then again, the proper way would be:
    >
    > MyClass(const MyClass &r) : x(r.x), y(r.y)
    > {
    > ++count;
    > id = count;
    > printf("Copy create (%d)\n",++count);

    [snip]
    forgive me the ++count inside the printf, it should be:
    printf("Copy create (%d)\n",count);

    Regards,

    Marcelo Pinto
    Marcelo Pinto, Oct 1, 2003
    #9
  10. djskrill

    djskrill Guest

    Thanks for the help.
    djskrill, Oct 1, 2003
    #10
    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. Apricot
    Replies:
    4
    Views:
    516
    velthuijsen
    Apr 16, 2004
  2. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,763
    Smokey Grindel
    Dec 2, 2006
  3. mlimber
    Replies:
    4
    Views:
    480
    Clark S. Cox III
    Jan 5, 2006
  4. Jimmy Hartzell
    Replies:
    0
    Views:
    411
    Jimmy Hartzell
    May 19, 2008
  5. Jimmy Hartzell
    Replies:
    2
    Views:
    1,163
    Jimmy Hartzell
    May 20, 2008
Loading...

Share This Page