一篇文章彻底弄懂C++虚函数的实现机制
介绍
C++的虚函数是实现多态的重要途径,本文将深入浅出地介绍C++虚函数的实现机制,希望能给大家带来一些帮助。
基本概念
静态绑定和动态绑定
在C++中,有两种绑定方式,即静态绑定(也称为静态链接)和动态绑定(也称为动态链接)。
静态绑定是指在编译期间确定函数的调用地址。这种方式的优点是执行速度快,缺点是不支持多态。
动态绑定是指在运行时确定函数的调用地址。这种方式支持多态,但执行速度稍慢。
多态
多态是指同一函数调用,由于对象不同可能会产生不同的行为。C++中的多态性可通过虚函数实现。经过虚函数声明的函数,可以在程序执行时动态地调用。
虚函数
C++中的虚函数是在基类中声明的,用virtual关键字修饰。在派生类中,如果定义了与基类同名、同参数列表的虚函数,则该函数会覆盖基类中的虚函数。
虚函数的调用有两种方式:静态绑定和动态绑定。静态绑定是指在编译期间确定虚函数的调用地址,适用于基类和派生类对象的普通函数调用;动态绑定是指在运行时根据对象的实际类型确定虚函数的调用地址,适用于基类指针或引用的虚函数调用。
虚函数的实现机制
在C++中,虚函数的实现机制主要基于虚函数表和虚函数指针。
虚函数表
每个包含虚函数的类都有一个虚函数表,用于存储该类所有虚函数的地址。虚函数表是一个只读的数据表,存储在程序的数据区,不同对象共享同一张虚函数表。
每个类只有一个虚函数表,而不是每个对象都有一个虚函数表。在类的构造函数中,将会产生一个隐式的指针vptr,并被初始化为虚函数表的地址。当派生类对基类虚函数进行覆盖时,基类中的虚函数表被派生类虚函数表所替换。
虚函数指针
每个包含虚函数的对象都有一个虚函数指针,用于指向该对象所属类的虚函数表。虚函数指针指向的虚函数表是在编译期间确定的,因此属于静态绑定。
虚函数调用
静态绑定的虚函数调用和普通的函数调用一样,通过函数名直接调用。静态绑定的虚函数调用的效率比动态绑定高,因为静态绑定是在编译期间确定函数地址的,省去了在运行时查找虚函数表的时间。
动态绑定的虚函数调用通过对象的虚函数指针来确定虚函数表,再根据虚函数表中的偏移量来确定实际调用的函数地址。动态绑定的虚函数调用相对于静态绑定而言效率低,因为需要在运行时查找虚函数表,并在虚函数表中查找偏移量。
示例说明
示例1
#include <iostream>
using namespace std;
class Base
{
public:
virtual void func() { cout << "Base::func()" << endl; }
};
class Derived : public Base
{
public:
void func() { cout << "Derived::func()" << endl; }
};
int main()
{
Base b;
Derived d;
b.func();
d.func();
Base* pb = &d;
pb->func();
return 0;
}
输出结果:
Base::func()
Derived::func()
Derived::func()
解释如下:
在第一个和第二个函数调用中,使用了静态绑定,直接调用了类自身的虚函数。在第三个函数调用中,使用了动态绑定,通过基类指针来调用派生类的虚函数,实现了多态。
示例2
#include <iostream>
using namespace std;
class Base
{
public:
virtual void func1() { cout << "Base::func1()" << endl; }
virtual void func2() { cout << "Base::func2()" << endl; }
};
class Derived : public Base
{
public:
void func1() { cout << "Derived::func1()" << endl; }
void func2() { cout << "Derived::func2()" << endl; }
};
int main()
{
Base b;
Derived d;
Base* pb = &b;
pb->func1();
pb->func2();
pb = &d;
pb->func1();
pb->func2();
return 0;
}
输出结果:
Base::func1()
Base::func2()
Derived::func1()
Derived::func2()
解释如下:
在第一个和第二个函数调用中,使用了静态绑定,直接调用了类自身的虚函数。在第三个和第四个函数调用中,使用了动态绑定,通过基类指针来调用派生类的虚函数,实现了多态。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:一篇文章彻底弄懂C++虚函数的实现机制 - Python技术站