一、继承和多态的实现原理

  1. 继承是面向对象的一个重要概念,继承允许一个类从另外一个类继承它的属性和方法。并且允许子类重写父类的方法,从而实现不同的功能。

  2. 虚函数是C++中实现动态多态的关键机制,虚函数是一个在基类中声明的函数,它可以被子类重写。在使用基类指针或者引用调用虚函数时,实际调用的是子类中的实现。

  3. 虚函数表是 C++中实现动态多态的机制(vtable)。

    1. 每个包含虚函数的类中,都有一个虚函数表,它存储了该类的虚函数地址。当一个类被实例化(就是声明这个类的对象)时,它的对象中会包含一个指向该类虚函数的指针(vptr)。
    2. 编译器会根据虚函数指针来找到该对象所属基类对应的虚函数表,然后根据函数在虚函数表中的位置找到实际要调用的函数。实际调用的函数是在运行时确定的,而不是在编译时确定的,这个过程叫做动态绑定。
    3. 虚函数表是属于类的,不是属于类对象的,每个类有一个虚函数表;虚函数指针是属于类对象的,它指向类的虚函数表。
  4. 静态绑定是C++中的另一种机制,主要实现函数重载(同一作用域内定义多个同名但是参数类型或参数个数不同的函数)、运算符重载。因为要调用哪个函数是在编译阶段确定的,而不是在运行时确定的,所以叫做静态绑定。

  5. 静态成员函数不能是虚函数。因为静态成员函数是属于类的,不属于类对象,不依赖任何对象,无法实现多态性。虚函数是为了在运行时根据类对象的类型确定要调用的函数,静态成员函数不属于对象,所以不能是虚函数。

  6. C++中,析构函数默认不是虚函数是为了减少开销、提高性能;因为虚函数实现动态绑定是依赖虚函数表的,每个对象都有一个虚函数指针,指向虚函数表,虚函数表存储了虚函数地址,定义为虚函数会增加对象的大小和内存开销。析构函数的作用是在对象被销毁时释放资源,在销毁对象时类型已经确定,无需再确认要调用的函数。基类的析构函数通常可以声明为虚函数,这是为了确保在删除基类指针时能正确调用派生类的析构函数。