C++ 语言标准关于这个问题的阐述非常清楚:当通过基类的指针去删除派生类的对象,而基类又没有虚析构函数时,结果将是不可确定的。这意味着编译器生成的代码将会做任何它喜欢的事:重新格式化你的硬盘,给你的老板发电子邮件,把你的程序源代码传真给你的对手,无论什么事都可能发生。
因为只有virtual函数才可能执行运行期绑定。
不光是析构函数,任何函数,只要不是virtual的,统统都是在编译时静态绑定的,所以从父类指针上调用,就只能是执行父类的那个函数。
注意重写的父类的函数如果在父类中是virtual,那么子类中无需声明为virtual也同样是virtual。
还有你可能误解了,《Effective C++》里并没有说析构函数必须是virtual。如果你的类永远不会做基类,那么就不需要virtual。
《Effective C++》也并没有说基类的析构函数就是virtual的,而只是“强烈建议”你把基类的析构函数设成virtual的。理论上,你完全可以不听他的建议。当然,其后果他也告诉你了。