1. C++ 多态分类及实现

  • 重载多态(Ad-hoc Polymorphism,编译期):函数重载、运算符重载(静态多态、静态编译)
  • 子类多态(Subtype Polymorphism,运行期):虚函数(动态多态、动态编译)
  • 参数多态(Parametric Polymorphism,编译期):类模板(泛型)、函数模板(函数指针)
  • 强制多态(Coercion Polymorphism,编译期/运行期):基本类型转换、自定义类型转换

2. 虚表指针、虚函数指针、虚函数表

  • 虚表指针:在含有虚函数的类的对象中,指向虚函数表的指针,在运行时确定
  • 虚函数指针:指向虚函数的地址的指针 {vfptr}
  • 虚函数表:在程序只读数据段,存放虚函数指针,如果派生类实现了基类的某个虚函数,则在虚函数表中覆盖原本基类的那个虚函数指针,在编译时根据类的声明创建 Shape::$vftable@
class Shape
{
public:
    virtual ~Shape(){
        cout << "~Shape()" << endl;
    }
};
class Point
{
public:
    ~Point(){
        cout << "~Point()" << endl;
    }
private:
    int m_x{0};
    int m_y{0};
    char m_c;
};
class Circle : public Shape
{
public:
    ~Circle(){
        cout << "~Circle()" << endl;
    }
private:
    Point m_p;
};
int main( )
{
    // 8    类中存有指向虚函数表的指针
    cout << sizeof(Shape) << endl;
    // 16   类中存有指向虚函数表的指针
    //      以及Point对象的大小(此时Point类中不包含任何变量),虽然真实大小是 8 + 1
    //      但是额外多的1个字节导致内存大小扩增了 8(每次扩增的最小数值是8 <alignment member> (size=7))
    cout << sizeof(Circle) << endl;
    // 8    类中的int占4个字节,char占1个字节
    //      但每次扩增的最小数值是4(<alignment member> (size=3))
    cout << sizeof(Point) << endl;

    Circle c;
    return 0;
}
Start
8
24
12
~Circle()
~Point()
~Shape()
0
Finish

Shape

// 没有虚函数
class Shape     size(1):
        +---
        +---

// 有虚析构函数
class Shape     size(8):
        +---
 0      | {vfptr}
        +---

Shape::$vftable@:
        | &Shape_meta
        |  0
 0      | &Shape::{dtor}

Shape::{dtor} this adjustor: 0
Shape::__delDtor this adjustor: 0
Shape::__vecDelDtor this adjustor: 0

Point

class Point     size(8):
        +---
 0      | m_x
 4      | m_y
 8      | m_c
        | <alignment member> (size=3)
        +---

Circle

class Circle    size(24):
        +---
 0      | +--- (base class Shape)
 0      | | {vfptr}
        | +---
 8      | Point m_p
        | <alignment member> (size=4)
        +---

Circle::$vftable@:
        | &Circle_meta
        |  0
 0      | &Circle::{dtor}

Circle::{dtor} this adjustor: 0
Circle::__delDtor this adjustor: 0
Circle::__vecDelDtor this adjustor: 0