Use explicitly defaulted destructors for base cases when possible, eliminate aggregate initialization constructors where possible, and push some more stuff to NSDMIs.
Apparently gcc does use final for devirtualization.