Object creation and delete in C++

156 Views Asked by At

I have below very simple code to understand C++ object creation and delete. The output is not really what I expected. Why?

class Box{

    public:
        static int count;
        Box(double x, double y, double z) : length(x),width(y),height(z){
            cout << "Box object created with " << length << " " << width << " " << height << endl;
            count++;
            cout << "Count after creation: " << count << endl;
        }
    
        ~Box(){
            cout << "Object deleted!" << endl;
            count--;
            cout << "Count after delete: " << count << endl;
        }        
    
        Box operator + (Box *b){
            return Box(length + b -> length, width + b -> width, height + b -> height);
        }
    
        Box operator + (Box b){
            return Box(length + b.length, width + b.width, height + b.height);
        }
    
    private:
        double length;
        double width;
        double height;
};

int Box::count = 0;

int main()
{    
    Box b1 = Box(1,1,1);
    Box b2 = Box(2,2,2);
    Box b3 = b1 + b2;
    cout << "Here I am expecting 3, but get 2: " << Box::count << endl;

    return 0;    
}

I run the code and got below output:

Box object created with 1 1 1
Count after creation: 1
Box object created with 2 2 2
Count after creation: 2
Box object created with 3 3 3
Count after creation: 3
Object deleted!
Count after delete: 2
Here I am expecting 3, but get 2: 2.   // I am expecting 3 there, b1, b2 and b3
Object deleted!
Count after delete: 1
Object deleted!
Count after delete: 0
Object deleted!
Count after delete: -1 // how can this been negative!
1

There are 1 best solutions below

0
Vlad from Moscow On

The unexpected behavior of the program is related to the declaration of the operator +:

Box operator + (Box b){
    return Box(length + b.length, width + b.width, height + b.height);
}

As the parameter does not accept an argument by reference then in this declaration

Box b3 = b1 + b2;

that is equivalent to

Box b3 = b1.operator +( b2 );

there is created a new object for the parameter Box b of the operator function using the default copy constructor. This object has the same value of count that is equal to 2 as the object b2.

Then due to the copy/move elision in this declaration

Box b3 = b1 + b2;

there is created the object b3 using the constructor

    Box(double x, double y, double z) : length(x),width(y),height(z){
        cout << "Box object created with " << length << " " << width << " " << height << endl;
        count++;
        cout << "Count after creation: " << count << endl;
    }

So the value of count for this object is equal to 3.

On the other hand, the parameter created in the operator + is deleted using the destructor. As a result the value of count is decremented and now is equal to 2 though there are alive 3 objects.

And these messages

Count after creation: 3
Object deleted!        // <===
Count after delete: 2  // <===

report about the deletion of the local object (parameter) of the operator functon.

So when the last object is destroyed the value of count becomes equal to -1.

You could declare the operator + the following way

Box operator + (const Box &b){
    return Box(length + b.length, width + b.width, height + b.height);
}

to get the expected result. In this case a redundant object of the type Box using the default copy constructor will not be created because the object b2 will be passed to the operator + by reference and neither intermediate object of the type Box will be created.

Otherwise you need to define the copy constructor explicitly incrementing count for a created new object.