新手关于虚函数的一点有关问题
新手关于虚函数的一点问题#include iostreamusing namespace stdclass Base{public:void run() { displ
新手关于虚函数的一点问题
#include <iostream>
using namespace std;
class Base{
public:
void run() { display(); }
virtual void display() { cout<< "Base" <<endl; }
};
class Drive: public Base{
public:
void display() { cout<< "Drive" <<endl; }
};
int main(void)
{
Base *p = new Drive;
p->run();
delete p;
system("PAUSE");
return 0;
}
这里输出的是Drive
说明产生了覆盖
我不太明白虚函数表到底属于什么???是属于一个类吗??每个类都有一个虚函数表吗???
那他覆盖的到底是谁的虚函数表??
虚函数
[解决办法]在单继承体系下,每一个带有virtual机制(virtual函数或virtual继承)的类都拥有一个虚函数表vtable。这个类的每一个类实例拥有一个指向该表的指针vptr。该类的vtable中的virtual函数如果在基类中也有定义,则在vtable中存储该类的函数地址而不是基类的函数地址,相当于覆盖了基类的这个函数地址。
[解决办法]当你使用“覆盖”特性的时候,你要调用派生类的同名函数,必须使用派生类的对象、派生类的指针或派生类的引用,而当你使用“多态”特性的时候,你要调用派生类的同名函数,必须创建一个派生类的对象后,使用基类的指针或基类的引用指向它
简而言之,“覆盖”和“虚函数表”没有任何关系
如果你觉得它们很相似,那你需要分别复习这两块基础知识,以避免它们在你脑中搅成一团
[解决办法]Base *p = new Derived;
用基类的指针或者引用指向派生类的地址,是多态的基本方法。虽然p是Base的指针,但实际的内存模型是派生类的,因为你new的是一个Derived。在内存中,模型是Derived的结构,因此vptr指向的是Derived类的vptr,不是Base的。
[解决办法]是通过指向子类对象的父类型指针调用虚函数,该对象起始地址保存了对应类型的虚函数表的指针,因此访问的是子类的虚函数表。
LZ还是找本书看看吧?推荐《Thinking in C++》。水平有限,三言两语说不清