动态绑定与虚函数

动态绑定 是与 静态绑定 相对立的概念,而绑定绑的是函数。

对于任何对象,其以函数名调用函数的时候,对于执行哪个函数是在编译时就能确定的,这叫静态绑定

而对于指针和引用,由于C++中允许基类指针(引用)指向派生类对象,这时候其虚函数被调用,具体执行哪个函数是与引用(指针)指向的对象是什么有关,这叫动态绑定

例子

现在定义一个基类 Person,其中有一个虚方法who:

class Person
{
public:
    virtual void who() {
        cout << "I am person" << endl;
    }
};

然后有一个派生类 Student

class Student
{
public:
    virtual void who() {
        cout << "I am student" << endl;
    }
};

主函数调用情况如下:

int main()
{
    Student s;
    Person p;
    Person &a = s;
    Person &b = p;
    a.who();
    b.who();
}

Note:

  1. a.who() 输出的是Student里的内容 I am student
  2. b.who() 输出的是Person里的内容 I am Person

纯虚函数

语法规则如下:

class A
{
    virtual void a() = 0;
}
  • =0标记该函数是个纯虚函数。

任何含有纯虚函数的类都是抽象类抽象类不能产生对象。

注意事项

  1. 构造函数不可以是虚函数
  2. 如果一个类被继承,析构函数最好定义为虚函数,否则可能产生问题。

虚函数如何实现

下面讲一种编译器实现虚函数的方法。

  1. 首先编译器会给每一个对象产生一个隐藏的表:表中存储所有虚函数的地址。
  2. 派生类先完整继承基类的虚函数表。
  3. 如果派生类重载了基类的虚函数,则会用派生类重载函数的地址代替原函数的地址,如果新定义了虚函数,则把新函数的地址也加入虚函数表。
  4. 当以指针(引用)形式调用虚函数时,按照调用的函数的序号对应到虚函数表上对应的函数执行。如调用第2个虚函数,则实际执行的是虚函数表中第二个函数。

results matching ""

    No results matching ""