c++中调用虚函数的时间复杂度

Time complexity to invoke virtual functions in C++

本文关键字:时间复杂度 函数 调用 c++      更新时间:2023-10-16

假设具有Base类型的继承层次结构,该继承层次结构具有F个虚函数,D个不同的派生类型,并假设每个派生类型覆盖所有虚函数。

为Base*类型的指针p调用其中一个虚函数的时间复杂度是多少?

还有,如果总共有O个对象(在类型中平均分配)并且所有对象都有相同的数据成员,那么系统的空间复杂度是多少?

调用函数的时间复杂度为0(1)。每个类都有一个虚函数表,它本质上是一个函数指针的结构体——每个对象都有一个指向这个虚函数表的指针,所以调用虚函数只是在虚函数表中查找函数指针并调用它。

0个对象的空间完备性为O(O),因为它在对象数量上是线性的。

对象大小计算为该对象的属性大小+指向虚表的指针大小

so if

class Base {
    int a;
    char b;
    virtual void f();
    virtual void g();
};

表示Base b的大小为sizeof(int) + sizeof(b) + sizeof一个实值表ptr

如果你说所有的对象(派生的和非派生的)有相同的成员,它们的大小是相同的

有一个指针指向一个包含所有虚函数的虚表,因此访问它并解引用一个函数是O(1)。

空间复杂度为O(F)(如果F是常量,则为O(1)),因为同一类的所有对象都有一个地址表。

摘自维基百科:对象的分派表将包含对象的动态绑定方法的地址。通过从对象的调度表中获取方法的地址来执行方法调用。分派表对于属于同一类的所有对象都是相同的,因此通常在它们之间共享。属于类型兼容类的对象(例如继承层次结构中的兄弟类)将具有具有相同布局的分派表:给定方法的地址将出现在所有类型兼容类的相同偏移位置。因此,从给定的调度表偏移量中获取方法的地址将获得与对象的实际类相对应的方法。