编译器会为每个有虚函数的类(不是类实例)维护一个虚函数表vftable,这些类的每个实例都含有一个vfptr,指向各自类的虚函数表,在虚函数表中,派生类的override函数会替换基类的对应函数,运行时,根据函数调用者的指针或者引用类型(基类还是派生类)来确定调用那个函数,就是运行时多态了。
推荐 http://blog.csdn.net/haoel/article/details/1948051/ ,该作者是muduo的作者,c++ primer评注版的作者,文章很详细。
如果基类析构函数不是虚函数,Base *d = new Derived(); 这样定义的d在析构的时候只会调用Base自己的析构函数,delete d; 运行的时候,Derived自己的数据成员不会被销毁,造成内存泄漏。
如果基类析构函数是虚函数,上面例子中d对象由于多态会执行Derived定义的析构函数,完全销毁Derived实例的数据成员,至于之后还调用了Base的析构函数,是由于编译器对派生类析构函数做了处理,使其执行后仍需调用其基类析构函数。
推荐 http://blog.csdn.net/haoel/article/details/1948051/ ,该作者是muduo的作者,c++ primer评注版的作者,文章很详细。
如果基类析构函数不是虚函数,Base *d = new Derived(); 这样定义的d在析构的时候只会调用Base自己的析构函数,delete d; 运行的时候,Derived自己的数据成员不会被销毁,造成内存泄漏。
如果基类析构函数是虚函数,上面例子中d对象由于多态会执行Derived定义的析构函数,完全销毁Derived实例的数据成员,至于之后还调用了Base的析构函数,是由于编译器对派生类析构函数做了处理,使其执行后仍需调用其基类析构函数。