Why the destructor of an object in an array isn't called when being replaced by another?

Viewed 70

Just see code

class SomeClass {
private:
    int i;
public:
    int getI() {
        return i;
    }

    SomeClass() {
        i = 0;
    }

    explicit SomeClass(int i) {
        this->i = i;
    }

    ~SomeClass(){
        cout << "SomeClass destructed with i=" << i << "." << endl;
    }
};

And the main function

int main() {
    auto* someClasses = new SomeClass[5];
    someClasses[2] = SomeClass(20);
    cout << "A new SomeClass Assigned." << endl;
    someClasses[2] = SomeClass(40);
    cout << "A new SomeClass Assigned." << endl;
    delete[] someClasses;
}

The array is initialized with all objects constructed with i=0, and we do some modification to someClasses[2].

When ending up an object, the destructor of the object should be called. However, the result shows that the destructor is not being invoked.

SomeClass destructed with i=20. // destructed after copy constructor is done.
A new SomeClass Assigned.
SomeClass destructed with i=40. // destructed after copy constructor is done.
A new SomeClass Assigned.
SomeClass destructed with i=0. // okay.
SomeClass destructed with i=0. // okay.
SomeClass destructed with i=40. // okay.
SomeClass destructed with i=0. // okay.
SomeClass destructed with i=0. // okay.

Process finished with exit code 0

If the destructor is designed not be called in this situation, how to assign a new object correctly to an existed array?

Using an object pointer array is an option but I'm just curious.

3 Answers

A destructor is called when the lifetime of an object ends (goes out of scope, delete is called on the pointer that was returned by new). When you do

someClasses[2] = SomeClass(40);

the lifetime of someClasses[2] doesn't end, you just give it a new value. It isn't until

delete[] someClasses;

when you delete the array that you end the lifetime of all the objects in the array, that the destructor is called.

It's not replaced with, it's assigned to. The object in the array continues live its lifetime happily, until the whole array is destroyed.

The assignments aren't calling a constructor or destructor, you're calling an assignment operator operator=. Since you didn't provide one for your SomeClass, the compiler generated one for you. This default operator= copies the member variable. For a simple class like yours this default is exactly what you need, which is why you see the result you expect in the array.

Related