虚函数,纯虚函数以及虚继承

虚函数是C++用于实现多态机制。如果父类不用virtual进行声明,则父类调用子类对象方法的时候仍然是父类方法。我们也可以在子类覆盖父类方法后面添加override检测。并且派生类通过指针或者引用指向派生类函数,则表现为派生类的特征。

例如:

class Parent
{
public:
    virtual void f()
    {
        printf("call parent");
    }

}

class Son
{
public:
    void f()
    {
        printf("call son");
    }

}

Parent* pParent = new Son();
pParent->f(); //call son

纯虚函数类似于Java当中的Interface使用如下,是没有对应的实现的。具有virtual声明的特点,方便使用多态。当包含纯虚函数的时候,类也将是抽象类,所以不能够定义抽象类的对象。

  • 抽象类中可以有多个纯虚函数

  • 不能声明抽象类的对象,但可以声明指向抽象类的指针变量和引用变量

  • 抽象类也可以定义其他非纯虚函数

  • 如果派生类中没有重新定义基类中的纯虚函数,则在派生类中必须再将该虚函数声明为纯虚函数

  • 从抽象类可以派生出具体或抽象类,但不能从具体类派生出抽象类

  • 在一个复杂的类继承结构中,越上层的类抽象程度越高,有时甚至无法给出某些成员函数的实现,显然,抽象类是一种特殊的类,它一般处于类继承结构的较外层

  • 引入抽象类的目的,主要是为了能将相关类组织在一个类继承结构中,并通过抽象类来为这些相关类提供统一的操作接口

virtual void f() = 0;

虚继承,是在符合继承的时候,使得派生类继承基类多次,但是只有一份基类的拷贝在派生对象当中

class 派生类 :virtual 基类1,virtual 基类2……
{
}

虚表:

对C++ 了解的人都应该知道虚函数(Virtual Function)是通过一张虚函数表(Virtual Table)来实现的。简称为V-Table。在这个表中,主是要一个类的虚函数的地址表,这张表解决了继承、覆盖的问题,保证其容真实反应实际的函数。这样,在有虚函数的类的实例中这个表被分配在了这个实例的内存中,所以,当我们用父类的指针来操作一个子类的时候,这张虚函数表就显得由为重要了,它就像一个地图一样,指明了实际所应该调用的函数。这里我们着重看一下这张虚函数表。C++的编译器应该是保证虚函数表的指针存在于对象实例中最前面的位置(这是为了保证取到虚函数表的有最高的性能——如果有多层继承或是多重继承的情况下)。 这意味着我们通过对象实例的地址得到这张虚函数表,然后就可以遍历其中函数指针,并调用相应的函数。

参考:

http://my.oschina.net/hnuweiwei/blog/280894

http://blog.csdn.net/haoel/article/details/1948051

原文地址:https://www.cnblogs.com/flashbird/p/4421787.html