In an std::vector<T>
the vector owns the allocated storage and it constructs T
s and destructs T
s. Regardless of T
's class hierarchy, std::vector<T>
knows that it has only created a T
and thus when .pop_back()
is called it only has to destroy a T
(not some derived class of T
). Take the following code:
#include <vector>
struct Bar {
virtual ~Bar() noexcept = default;
};
struct FooOpen : Bar {
int a;
};
struct FooFinal final : Bar {
int a;
};
void popEm(std::vector<FooOpen>& v) {
v.pop_back();
}
void popEm(std::vector<FooFinal>& v) {
v.pop_back();
}
https://godbolt.org/z/G5ceGe6rq
The PopEm
for FooFinal
simply just reduces the vector's size by 1 (element). This makes sense. But PopEm
for FooOpen
calls the virtual destructor that the class got by extending Bar
. Given that FooOpen
is not final, if a normal delete fooOpen
was called on a FooOpen*
pointer, it would need to do the virtual destructor, but in the case of std::vector
it knows that it only made a FooOpen
and no derived class of it was constructed. Therefore, couldn't std::vector<FooOpen>
treat the class as final and omit the call to the virtual destructor on the pop_back()
?