经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C++ » 查看文章
c++虚函数与虚函数表原理
来源:jb51  时间:2021/12/9 9:11:52  对本文有异议

1.什么是虚函数?

virtual 修饰的成员函数叫虚函数

小知识:?没有虚构造函数??????? 不写虚函数,没有默认的虚函数

普通函数不影响类的内存:

  1. class MM
  2. {
  3. public:
  4. void print()
  5. {
  6. cout << "普通函数"<< endl; //普通函数不影响类的内存<--->普通函数存在另一段内存中
  7. }
  8. protected:
  9. };
  10.  
  11. void testVirtual()
  12. {
  13. //C语言不允许存在空的结构体
  14. cout << sizeof(MM) << endl;/*(没有数据成员的)空的类或者结构体 占用1字节 用1字节标识当
  15. 前内存为结构体内存*/
  16. }
  17. int main()
  18. {
  19. testVirtual();
  20. return 0;
  21. }
  22. /*输出*/
  23.  
  24. /* 1 */
  25.  

2.虚函数会影响类的内存

增加一个指针的内存,32位操作系统多4个字节 ,64位操作系统多8个字节

  1. #include <iostream>
  2. using namespace std;
  3. class MM
  4. {
  5. public:
  6. virtual void print1()
  7. {
  8. cout << "虚函数1"<< endl;
  9. }
  10. /*virtual void print2()
  11. {
  12. cout << "虚函数2" << endl;
  13. } 无论多少个虚函数,增加的字节就是一个指针的字节--->多了一个虚函数,还是4个字节*/
  14. protected:
  15. };
  16. void testVirtual()
  17. {
  18. cout << sizeof(MM) << endl;
  19. }
  20. int main()
  21. {
  22. testVirtual();
  23. return 0;
  24. }
  25. /*输出*/
  26.  
  27. /* 4 */

小知识:一旦有了数据,标识位就不需要存在了

  1. class A
  2. {
  3. int num; //输出4而不是5 (4+1)
  4. };
  5. class B
  6. {
  7. //用1字节标识当前内存为结构体内存
  8. };
  9. void testVirtual()
  10. {
  11.  
  12. cout << sizeof(A) << endl;
  13. cout << sizeof(B) << endl;
  14. }
  15. int main()
  16. {
  17. testVirtual();
  18. return 0;
  19. }
  20.  
  21. /*输出*/
  22.  
  23. /*4
  24. 1*/
  25.  

3.了解虚函数表--->通过虚函数表的指针去访问数据

就是一个指针存储所有虚函数的首地址(虚函数函数名)<--->函数指针

只有指针可以操作一段内存(4字节)

/*无论多少个虚函数,增加的字节就是一个指针的字节*/
所有的虚函数其实是 用一个函数指针去存储的 ,把 这个函数指针指向的这一段内存 称为虚函数表

  1. #include <iostream>
  2. using namespace std;
  3. class MM
  4. {
  5. public:
  6. virtual void print1()
  7. {
  8. cout << "虚函数1"<< endl;
  9. }
  10. virtual void print2()
  11. {
  12. cout << "虚函数2"<< endl;
  13. }
  14. protected:
  15. };
  16. void testVirtual()
  17. {
  18. //虚函数表
  19. MM mm; //构建一个对象
  20. int** vptr = (int** )&mm; //定义一个二级指针&对象的地址 强转类型
  21. typedef void(*PF)(); //函数指针定义别名
  22. PF func = (PF)vptr[0][0]; //把地址转为函数指针,访问第一个函数指针的地址
  23.  
  24. func(); //通过虚函数表的函数指针调用第一个虚函数
  25. func = (PF)vptr[0][1];
  26. func(); //调用第二个虚函数
  27. }
  28. int main()
  29. {
  30. testVirtual();
  31. return 0;
  32. }
  33. /*输出*/
  34.  
  35. /*虚函数1
  36. 虚函数2*/
  37.  

4.虚函数声明

虚函数可以在类中声明,在类外实现,不再需要virtual修饰词,只要类名限定就可以了

  1. class MM
  2. {
  3. public:
  4. virtual void print3();
  5. protected:
  6. };
  7. void MM::print3() {
  8. cout << "虚函数3" << endl;
  9.  
  10. }
  11. int main()
  12. {
  13. MM mm;
  14. mm.print3();
  15. return 0;
  16. }
  17. /*输出*/
  18.  
  19. /*虚函数3*/

到此这篇关于c++虚函数与虚函数表原理的文章就介绍到这了,更多相关c++虚函数与虚函数表内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号