虚函数,抽象函数
class Base
{
public:
void do(){}
}
class Son:public Base
{
public:
void do(){}//覆盖
}
1、虚函数
父类和子类都有一个方法:do();但是通过子类对象指针访问这个do方法的时候,编译器会选择基类的do()来实现,而不是子类的:
Son son;
Base *p=&son;
p->do();
为了使son对象可以使用自己的do方法,可以在Base的do方法前面加virtual:virtual void do(){}
2、虚函数表
#include <iostream> using namespace std; class A { public: int i; virtual void func() {} virtual void func2() {} }; class B : public A { int j; void func() {} }; int main() { cout << sizeof(A) << ", " << sizeof(B); //输出 8,12 return 0; }
每个有虚函数的类都有一个虚函数表V-Table,虚函数表中列出了该类的全部虚函数地址,虚函数表供当前类的所有对象共有。
编译器为每一个有虚函数的对象都自动生成了一个虚函数指针,位于对象内存的前面4个字节【32位编译器】,这个指针指向虚函数表。
如果类被继承了,并且虚函数被重写了,那被重写的虚函数则在虚函数表中被替换【父类的被替换成子类的】,如下图B虚函数表中,func函数被替换成B类的【因为被重写了】,而func2保持不变,还是使用A类的。
不管是A指针指向B对象,还是B指针指向B对象,最后调用的函数都应该是B对象中的虚函数。因为虚函数指针是属于对象的,所以最后一定是取的B对象的前4个字节作为虚函数指针,所以最后指向的是B类的虚函数表。
【即:由当前对象决定调用父类的虚函数还是子类的虚函数】
3、抽象函数
即这个Base的do方法不实现,永远由它的子类来实现(空壳),先加virtual,再加=0:virtual void do()=0;
长风破浪会有时,直挂云帆济沧海!
可通过下方链接找到博主
https://www.cnblogs.com/judes/p/10875138.html