-1

Yes I know this question has been asked and answered a lot of times and I've tried to understand the previous posts on this (and believe I've tried) but I seriously cannot grasp the concept.

In my program below, the class A array a is created and the default constructor is called four times for each respective element in the array. This part I get. The pointer p is assigned the class object array a. I imagine that p is now pointing to the first element in the array. Now this is where I get lost. The destructor is called 4 times. I've read a lot of explanations but they only seem to confuse me more. I'd really just like a simple explanation of why this is happening.

I'm sorry if this is irritating to ask this again (though I'm sure I won't be the last) but any help from those willing would be greatly appreciated.

My Program plus the output:

#include <iostream.h>
  class A
  {
  public:
      A(int i)
      {  a=i;  }
      A()
      {
         a=0;
         cout<<"Default constructor called."<<a<<endl;
     }
     ~A()
     {  cout<<"Destructor called."<<a<<endl;  }
     void Print()
     {  cout<<a<<endl;  }
 private:
     int a;
 };
 void main()
 {
     A a[4],*p;
     int n=1; 
     p=a;
     for(int i=0;i<4;i++)
         a[i]=A(++n);
     for(i=0;i<4;i++)
          (p+i)->Print();
 }

Output:

 Default constructor called. 0
 Default constructor called. 0
 Default constructor called. 0
 Default constructor called. 0
 Destructor called. 2
 Destructor called. 3
 Destructor called. 4
 Destructor called. 5
 2
 3
 4
 5
  Destructor called. 5
  Destructor called. 4
  Destructor called. 3
  Destructor called. 2
Emmanuel N K
  • 8,710
  • 1
  • 31
  • 37

2 Answers2

2

A(++n) creates a temporary object that automatically gets destroyed shortly after being created. This accounts for the first batch of destructor calls.

NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • Why does it go out of scope immediately after assignment and not when the program terminates? – Emmanuel N K Dec 28 '13 at 14:14
  • 3
    Because it's not needed anymore (remember: it was copied, so in `A[i]` is a copy, but the original is not needed anymore). That's the case for all constructor calls which are part of an expression: they exist temporarily until we know what to do with them. In some cases they are copied, in some they are moved away (since C++11), in some cases they are really only needed temporarily (e.g. for a function call with const ref parameter). One exception is initial "assignment" which is not really assignment but initialization (like your `int n = 1`) – leemes Dec 28 '13 at 14:16
  • 1
    @nilerafter24: In short, that's how temporaries work in C++. See, for example, http://stackoverflow.com/questions/10897799/temporary-objects-when-are-they-created-how-do-you-recognise-them-in-code – NPE Dec 28 '13 at 14:16
  • Okay I've finally understood this. What was really confusing me I think, was that I was equating the way assignment operators and copy constructors work. But thats all cleared up now. Thanks. – Emmanuel N K Dec 28 '13 at 14:32
2

Commented version of your code:

void main()
{
    A a[4]; // Create 4 A : 4 calls to A().
    A* p;
    int n = 1; 
    p = a;
    for (int i = 0; i < 4; i++) {
        ++n;
        a[i] = A(n); // construct temporary A(n); call A(n), assign it into a[i]
                     // then call ~A();
    }
    for (int i = 0; i < 4; i++)
         (p + i)->Print();
 } // A a[4] goes out of scope and so call ~A() in reverse order.
Jarod42
  • 203,559
  • 14
  • 181
  • 302