zoukankan      html  css  js  c++  java
  • 关于虚函数,类的内存分布以及类的成员函数调用原理

    1.类的内存分布

    空类为了占位,空间占一个字节

    成员函数,静态函数,静态变量并不占内存(不和类放在一起)

    所有的虚函数也并不和类放在一起,而是将所有的虚函数构造成一个虚函数表,用一个指针指向这个虚函数表,类仅仅存储这个指针,一个指针在32位的机器上占四个字节

    所有的非静态成员变量占内存

    因此,类的内存分布=所有的非静态成员变量+虚指针(自创的名词:即指向虚函数表的指针)

    2.虚函数的原理

    一个非继承的类:一个虚指针(指向他的虚函数表)、

    一个单继承的类:一个虚指针(指向他的虚函数表,这个虚函数表=复制自父类的虚函数表(更新自己重写的部分虚函数,没有更新的直接复制)+新的自己的虚函数)

    一个多继承的类:多个虚指针:

                  一个主虚指针:存放着复制自主基类的虚函数表(更新自己重写的部分虚函数,没有更新的直接复制)+新的自己的虚函数

                 多个从虚指针:存放着复制自其它基类的虚函数表(更新自己重写的部分虚函数,没有更更新的直接复制)

    3.函数调用原理

      以前都理解错了啊,其实函数调用原理和->运算符和.运算符并没由任何关系

      函数调用其实是有两种:动态绑定静态绑定

      前者相信很多人面试的时候都被问到过!然而我以前只知道个皮毛!!!!

      所谓动态绑定就是一个类的指针或者引用在调用一个虚函数的时候,并不直接指向该函数的地址,而是指向这个类的虚函数表,比如

      A& a;

      a->func();//假设func()是类A的虚函数

      这里的调用关系实质是A::this->vfptr;//编译阶段就调到这里,到运行时,就vfptr->func()

      这就是所谓的动态绑定

      而静态绑定就是

      A a;

      a.func();//假设func是个虚函数

      这里的调用关系就是直接指向func()函数的地址,不通过A::this->vfptr,而是直接指向func()的地址

      另外:这个例子中a.func()调用的是A类中的虚函数(假设已重写),而不是父类中的虚函数,

    总结:

      假设用得是.运算符,则肯定是静态绑定,不管是不是虚函数

      假设用得是->运算符,且调用函数是虚函数,则肯定是动态绑定,若不是虚函数,肯定不是动态绑定

     

    有题为证(一道笔试题引发的血案,深入探讨了所谓的动态绑定)

    4、以下代码

      [cpp] view plaincopy

      class classA

      {

      public:

      classA()

      {

      clear();

      }

      virtual ~classA()

      {

      }

      void clear()

      {

      memset(this , 0 , sizeof(*this));

      }

      virtual void func()

      {

      printf("func ");

      }

      };

      class classB : public classA

      {

      };

      int main(void)

      {

      classA oa;

      classB ob;

      classA * pa0 = &oa;

      classA * pa1 = &ob;

      classB * pb = &ob;

      oa.func(); // 1

      ob.func(); // 2

      pa0->func(); // 3

      pa1->func(); // 4

      pb->func(); // 5

      return 0;

      }

      A、func func 执行出错 执行出错 func

      B、执行出错 func 执行出错 执行出错 func

      C、执行出错 执行出错 执行出错 执行出错 执行出错

      D、func func func func func

      E、func func 执行出错 func func

      F、以上选项都不对

  • 相关阅读:
    北极星杯 awd复现
    5,linux入门到上手-文件与文件系统的压缩,打包与备份
    4,linux入门到上手-文件与目录相关操作
    ctf中 preg_match 绕过技术 | 无字母数字的webshell
    巅峰极客 2019部分题解 writeup
    使用python爬去中国最好大学排名2016年
    python进制转换
    python应用-爬取猫眼电影top100
    3,linux入门到上手-文件权限管理与配置
    DNS、域、域名及FQDN 概念
  • 原文地址:https://www.cnblogs.com/YTYMblog/p/6444652.html
Copyright © 2011-2022 走看看