Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ destructor destructing more objects than constructor created

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.

like image 252
celeritas Avatar asked Dec 02 '22 18:12

celeritas


1 Answers

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.

like image 183
Strings Avatar answered Dec 10 '22 12:12

Strings