21xrx.com
2024-12-22 15:52:09 Sunday
登录
文章检索 我的文章 写文章
C++虚函数表的原理和应用
2023-07-14 21:27:37 深夜i     --     --
C++ 虚函数表 原理 应用

C++的虚函数表(Virtual Function Table,VTable)是实现多态性(Polymorphism)的机制之一,是C++的一个重要特性。本文将详细介绍C++虚函数表的原理和应用。

1.虚函数的定义

在C++中,通过使用virtual关键字修饰成员函数来定义虚函数。虚函数的声明如下:


class Base {

public:

  virtual void foo()

    // do something

  

};

class Derived : public Base {

public:

  virtual void foo() override

    // do something else

  

};

上面的代码中,Base类和Derived类都有一个名为foo的虚函数,其中Derived类通过override关键字重载了Base类的虚函数。

2.虚函数表的组成

在C++中,每个对象都有一个指向虚函数表的指针(vptr),虚函数表是一个存储了虚函数地址的数组。

假设有如下定义:


class A {

public:

  virtual void foo() {

    std::cout << "A::foo()" << std::endl;

  }

  virtual void bar() {

    std::cout << "A::bar()" << std::endl;

  }

};

class B : public A {

public:

  void bar() override {

    std::cout << "B::bar()" << std::endl;

  }

};

那么,A类和B类的虚函数表如下所示:

| 虚函数表 |      |

| --------- | --------- |

| 虚函数地址1 | A::foo() |

| 虚函数地址2 | A::bar() |

| 虚函数表 |      |

| --------- | --------- |

| 虚函数地址1 | B::foo() |

| 虚函数地址2 | B::bar() |

从上面的表格中可以看出,虚函数表与类相关,每个类的虚函数表中存储了当前类的虚函数地址,以及其继承关系中父类的虚函数地址。如果当前类重载了父类的虚函数,就用当前类的虚函数地址替换掉父类的虚函数地址。

3.虚函数表的使用

每个对象都有一个指向所属类虚函数表的指针vptr,这个指针可以通过调用对象的虚函数来访问虚函数表中存储的虚函数地址,从而执行相应的函数。

示例代码如下:


int main() {

  A* a = new A();

  a->foo(); // A::foo()

  a->bar(); // A::bar()

  B* b = new B();

  b->foo(); // A::foo()

  b->bar(); // B::bar()

  A* c = new B();

  c->foo(); // A::foo()

  c->bar(); // B::bar()

  return 0;

}

以上代码中,a和b都是指向不同类的对象指针。当调用对象的虚函数时,程序会首先检查vptr指向的虚函数表,根据虚函数表中存储的虚函数地址,找到对应的虚函数,并调用它。需要注意的是,如果派生类重载了基类的虚函数并且使用了override关键字,就会替换掉基类虚函数表中相应虚函数的地址。

4.总结

本文详细介绍了C++虚函数表的原理和应用。虚函数表是C++实现多态性的关键,使用虚函数表可以实现派生类对基类虚函数的重载和覆盖等多态性行为。掌握虚函数表的原理和使用方法,可以帮助开发者更好地理解C++中的多态特性。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复