Firstly, objects with automatic storage are automatically deleted a the end of a scope. So declaring restaurant restaurant;
will construct a restaurant but will also delete it automatically at the end of the main
function.
Try this:
struct A {
A() { std::cout << "A()"; }
~A() { std::cout << "~A()"; }
};
struct B : A {
B() { std::cout << "B()"; }
~B() { std::cout << "~B()"; }
};
auto main() -> int {
B b;
} // b destroyed here
The output is:
A()B()~B()~A()
It behave like a stack. First, the base class is constructed, then the derived class. Then, it destroy the derived first and the base class at the end.
This behaviour is extremely important for most C++ idiom.
Consider this:
struct A {
A() : arr(new int[3]{1, 2, 3}) {}
~A() { delete[] arr; }
int* arr = nullptr;
};
struct B : A {
B() {}
~B() {}
auto stuff() -> int {
return std::accumulate(arr, arr + 3, 0);
}
};
auto main() -> int {
B b;
return b.stuff(); // returns 1 + 2 + 3
}
What would happen if the constructor A()
was not executed first? The array would be null. That would be bad.
Also... what would happen if the destructor ~A()
was not executed? That would be a memory leak. That would be super bad.
Constructors and destructors have a guaranteed execution and a well defined order. This is why you don't have to call super()
and ~super()
in all of you constructors and destructor. Because you could forget to call it. Destructor and constructor is not something you want to forget to call, or else there would be no advantages over just using free function like in C.