Discussion
This simple guideline illustrates a subtle issue and reflects modern uses of inheritance and object-oriented design principles.For a base class Base , calling code might try to delete derived objects through pointers to Base . If Base 's destructor is public and nonvirtual (the default), it can be accidentally called on a pointer that actually points to a derived object, in which case the behavior of the attempted deletion is undefined. This state of affairs has led older coding standards to impose a blanket requirement that all base class destructors must be virtual. This is overkill (even if it is the common case); instead, the rule should be to make base class destructors virtual if and only if they are public.Items 35 through 37). Recall that for each member function participating in that abstraction, you need to decide:
- Whether it should behave virtually or not.
- Whether it should be publicly available to all callers using a pointer to Base or else be a hidden internal implementation detail.
As described in Item 39, for a normal member function, the choice is between allowing it to be called via a Base* nonvirtually (but possibly with virtual behavior if it invokes virtual functions, such as in the NVI or Template Method patterns), virtually, or not at all. The NVI pattern is a technique to avoid public virtual functions.Items 39 and 55.)Corollary: Always write a destructor for a base class, because the implicitly generated one is public and nonvirtual.