zoukankan      html  css  js  c++  java
  • this指针的调整

      我们先来看一段代码:

     1 #include <iostream>
     2 
     3 using namespace std;
     4 class A 
     5 {
     6 public:
     7     int a;
     8     A( )
     9     {
    10         printf("A:A()的this指针是%p
    ", this);
    11     }
    12 
    13     void funcA( )
    14     {
    15         printf("A:funcA()的this指针是%p
    ", this);
    16     }
    17 };
    18 
    19 class B
    20 {
    21 public:
    22     int b;
    23     B( )
    24     {
    25         printf("B:B()的this指针是%p
    ", this);
    26     }
    27 
    28     void funcB( )
    29     {
    30         printf("B:funcB()的this指针是%p
    ", this);
    31     }
    32 };
    33 
    34 class C :public A, public B
    35 {
    36 public:
    37     int c;
    38     C( )
    39     {
    40         printf("C:C()的this指针是%p
    ", this);
    41     }
    42     void funcC()
    43     {
    44         printf("C:funcC()的this指针是%p
    ", this);
    45     }
    46 };
    47 
    48 int main()
    49 {
    50     cout << sizeof(A) << endl;
    51     cout << sizeof(B) << endl;
    52     cout << sizeof(C) << endl;
    53     
    54     C cobj;
    55 
    56     cobj.funcA();
    57     cobj.funcB();
    58     cobj.funcC();
    59     return 0;
    60 }

    运行结果为:

    第一个基类子对象A的起始地址是与派生类对象C是重合的。我们来看一张图片:

      上图演示了this指针是如何调整的。在派生类的对象中,基类是作为派生类的子对象存在的,称为基类子对象,当派生类只继承于一个基类时,基类子对象的起始地址是与派生类对象相同的,而当派生类同时继承于多个基类时(多重继承,这里暂时不考虑虚拟继承)

    第一个基类子对象的起始地址是与派生类对象重合的,而后续基类子对象的起始地址与派生类对象依次相差前面的基类子对象的长度,比如,D同时派生于A、B、C。D对象的起始地址是0,那么A子对象的起始地址也是0,B子对象的起始地址是0+sizeof(A),而C对象的起始地址为0 + sizeof(A) + sizeof(B)。上面的例子C类派生于A,B。C类对象的地址是006FFD4C,那么A子对象的起始地址和C类对象的起始地址是一样的为006FFD4C,B类对象的起始地址为006FFD4C + sizeof(A) = 006FFD4C + 4 = 006FFD50

    如果我们把程修改成如下,输入结果会怎么样呢?

     1 #include <iostream>
     2 
     3 using namespace std;
     4 class A 
     5 {
     6 public:
     7     int a;
     8     A( )
     9     {
    10         printf("A:A()的this指针是%p
    ", this);
    11     }
    12 
    13     void funcA( )
    14     {
    15         printf("A:funcA()的this指针是%p
    ", this);
    16     }
    17 };
    18 
    19 class B
    20 {
    21 public:
    22     int b;
    23     B( )
    24     {
    25         printf("B:B()的this指针是%p
    ", this);
    26     }
    27 
    28     void funcB( )
    29     {
    30         printf("B:funcB()的this指针是%p
    ", this);
    31     }
    32 };
    33 
    34 class C :public A, public B
    35 {
    36 public:
    37     int c;
    38     C( )
    39     {
    40         printf("C:C()的this指针是%p
    ", this);
    41     }
    42     void funcC()
    43     {
    44         printf("C:funcC()的this指针是%p
    ", this);
    45     }
    46     void funcB()
    47     {
    48         printf("C:funcB()的this指针是%p
    ", this);  //新增加的代码
    49     }
    50 };
    51 
    52 int main()
    53 {
    54     cout << sizeof(A) << endl;
    55     cout << sizeof(B) << endl;
    56     cout << sizeof(C) << endl;
    57     
    58     C cobj;
    59 
    60     cobj.funcA();
    61     cobj.funcB();
    62     cobj.funcC();
    63     return 0;
    64 }

    输出结果为:

    可以看到,此时三个值都相同了,C类override基类子对象B的funcB函数,此时funB()中的this指针指向C对象的起始地址。

  • 相关阅读:
    JavaScript 属性和方法的类型
    2013年系统集成项目管理工程师真题 上午 附参考答案
    Openssl 学习—1.概述
    完成端口笔记
    激活 Microsoft office 2010、visio 2010方法
    Openssl 学习—0.基础
    socket编程入门(函数)
    Openssl 学习—3.RSA
    Openssl 学习—2.BIGNUM结构
    为什么百度有啊还不开始宣传!
  • 原文地址:https://www.cnblogs.com/cxq0017/p/10657097.html
Copyright © 2011-2022 走看看