3

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.

iry
  • 375
  • 1
  • 2
  • 8

3 Answers3

3

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.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • So = operator is just an operator to modify the content of the object to make the object same as the object on the right side of the operator, I'm I right this time :P? I learn Java before C++ and assigning pointers are giving me kind of sense that = operator is used to replacing the previous object by a new object, so sorry for my ignorance xD – iry Sep 05 '18 at 20:11
  • 2
    @iry Java and C++ are very different. In C++ we have value semantics and variables are objects, not pointers like they are in Java (very generalized, there are pointers to in C++). When you write `A = B` you don't make `A` point to the same object `B` points to but instead you you copy the object `B` into `A` so you now have two objects with the same value. If you have not done so I suggest you get yourself a [good C++ book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). Trying to code C++ as Java will just lead to issues. – NathanOliver Sep 05 '18 at 20:16
2

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.

bipll
  • 11,747
  • 1
  • 18
  • 32
2

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.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622