Reputation: 388
I am trying to get familiar with constructors and destructors in C++. The below program simply creates a complex number, prints it on the stdio and exits. I have created 3 objects (1. using default constructor, 2. using explicit constructor and third using the copy constructor. Before exiting, it destructed 4 objects. Why my program below is destructing more objects than the constructor ever created?
#include <iostream>
using namespace std;
class complex
{
private: float a; float b;
public: float real(){return a;};
float imag(){return b;};
complex(){a=0.0; b=0.0;cout << "complex no. created."<<endl;};
complex(float x, float y){a=x; b=y;};
~complex(){cout << "complex no. with real part " << this->real() << " destroyed" << endl;};
void display(){cout << a << '+' << b << 'i';}
friend ostream& operator<< (ostream & sout, complex c)
{
sout << c.a << '+' << c.b << 'i' << "\n";
return sout;
}
};
main()
{
complex c1;
complex c2(1.0,1.0);
c1.display();
cout << endl;
c2.display();
cout << endl;
cout << c2.imag() << endl;
complex c3 = c2; // this uses the default 'copy constructor'
c3.display();
cout << endl;
cout << c2;
}
The output that I am getting is:
complex no. created.
0+0i
1+1i
1
1+1i
1+1i
complex no. with real part 1 destroyed
complex no. with real part 1 destroyed
complex no. with real part 1 destroyed
complex no. with real part 0 destroyed
Just for the sake of completion, I have tried this on CC as well as g++ compilers. And both of them behave same.
Upvotes: 4
Views: 916
Reputation: 550
Add the copy constructor, insert breakpoints and observe :)
complex(complex ©complex)
{
cout << "hello from the copy constructor." << endl;
*this = copycomplex;
};
Upvotes: 2
Reputation: 1683
friend ostream& operator<< (ostream & sout, complex c)
is passing complex by value, so another complex is being created.
change the function parameters to
friend ostream& operator<< (ostream & sout, const complex& c)
This will pass complex by reference (saving a copy being created and destroyed).
The const qualifier means that your function will not modify the contents of c. Without a const qualifier on your function, it would not accept constant complex objects, so the following code would cause an error (which is not what you want).
const complex a_constant_complex(1.0,1.0);
cout << a_constant_complex << endl;
Other notes about your code
Also if at all possible get out of the habit of using 'using namespace std;'. Pulling the whole of the std namespace into your global namespace is not a good thing.
And the trailing '<< "\n"' in the operator<< shouldn't be there either. The purpose of operator<< is to send yourself to the stream, if the caller wants a newline after it, they'll add a << endl like I did in my constant example.
Upvotes: 8
Reputation: 52471
Your class has another constructor - an implicitly defined copy constructor. It doesn't print anything, but objects get constructed with it nevertheless.
Define your own copy constructor, print something in it - then you'll see constructors and destructors line up.
Your operator<<
takes complex
by value, so a temporary is created whenever you call it. That's where the "extra" constructor/destructor pair comes from.
Upvotes: 8