《虚函数的工作原理详解-C++ Primer上讲的简单易懂》

最近看C++ Primer第六版,无意中看到第十三章的虚函数的工作原理,发现比我之前看的人家写的博客还要通俗易懂还很简洁,所以分享出来。

编译器处理虚函数的方法是:
给每个对象添加一个指针,存放了指向虚函数表的地址,虚函数表存储了为类对象进行声明的虚函数地址。比如基类对象包含一个指针,该指针指向基类所有虚函数的地址表,派生类对象将包含一个指向独立地址表的指针,如果派生类提供了虚函数的新定义,该虚函数表将保存新函数的地址,如果派生类没有重新定义虚函数,该虚函数表将保存函数原始版本的地址。如果派生类定义了新的虚函数,则该函数的地址将被添加到虚函数表中,注意虚函数无论多少个都只需要在对象中添加一个虚函数表的地址。
在这里插入图片描述
调用虚函数时,程序将查看存储在对象中的虚函数表地址,转向相应的虚函数表,使用类声明中定义的第几个虚函数,程序就使用数组的第几个函数地址,并执行该函数。

使用虚函数后的变化:
(1) 对象将增加一个存储地址的空间(32位系统为4字节,64位为8字节)。
(2) 每个类编译器都创建一个虚函数地址表
(3) 对每个函数调用都需要增加在表中查找地址的操作。

虚函数的注意事项

  1. 总结前面的内容
    (1) 基类方法中声明了方法为虚后,该方法在基类派生类中是虚的。
    (2) 若使用指向对象的引用或指针调用虚方法,程序将根据对象类型来调用方法,而不是指针的类型。
    (3)如果定义的类被用作基类,则应将那些要在派生类中重新定义的类方法声明为虚。
  2. 构造函数不能为虚函数。
  3. 基类的析构函数应该为虚函数。
  4. 友元函数不能为虚,因为友元函数不是类成员,只有类成员才能是虚函数。
  5. 如果派生类没有重定义函数,则会使用基类版本。
  6. 重新定义继承的方法若和基类的方法不同(协变除外),会将基类方法隐藏;如果基类声明方法被重载,则派生类也需要对重载的方法重新定义,否则调用的还是基类的方法。

猜你喜欢

转载自blog.csdn.net/HuYingJie_1995/article/details/88085213