虚函数,抽象函数

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/5885452.html