I' ve read some articles, and as they say, main virtual destructor use cases are:
derived classes may have dynamic data allocation from heap, i.e. "own" that data object. So, they need some deletion routine in destructor. Deletion through base class pointer requires
virtualdeclaration of destructors in all derived class till those with dynamic data allocation (base class also requires it)this class has
virtualmethods. But this is unclear for me. Just callingvirtualmethods through base class pointer always results in the-most-derived-realization calls. They only exclusion for that rule is construction phase. Literaly, during itthisobject is not a derived type yet, even if later will be. Ok, what about destruction phase? As I understood, the rule is in the backward order. No matter, was destructor of some class in hierarchy declared asvirtual, during each destructorthispointer is used as if of this class type, any derived were already been destroyed due tovirtuald-r, or not destroyed (and that hypothetically may be ok in some design). Maybe this is the case, why d-r must be virtual? Vtable will have entries for derived class, and callingvirtualmethods in some base class from d-r will result in UB? Ok, but this rule applies only to case when this class calls somevirtualmethods in d-r, and they do have realization in derived classes.
My opinion, that there is also may be a case with no dynamic data allocation, no virtual methods in all hierarchy, but still derived destructors may do some critical tasks upon deletion (syncs, unlocks and so on). And we need virtual d-r in base class. May be such cases are results of bad design.
But anyway, developer of some public class cannot 100% know, if derived class will or not use some virtual methods in d-r, or allocate dynamic data. So, am I correct to say, that any public class, not declared as final, has to declare d-r as virtual? Only final keyword guarantees that any pointer to this class will always be of this type, and so, could be safely deleted non-virtually.