【问题标题】:Why "this" pointer has same value inside derived and first base class为什么“this”指针在派生类和第一个基类中具有相同的值
【发布时间】:2020-05-22 20:23:03
【问题描述】:

考虑这些将充当基类的类:

struct Base1 {
   int b1;
   void print_Base1_addr() const { std::cout << this << '\n'; }
};

struct Base2 {
   int b2;
   void print_Base2_addr() const { std::cout << this << '\n'; }
};

如果Derived继承自Base1Base2

struct Derived: Base1, Base2 {
   int i;
   void print_addr() const { std::cout << this << '\n'; }
};

然后此代码在DerivedBase1 中为this 打印相同的地址,但在Base2 中却没有:

Derived d{}; 

d.print_addr();
d.print_Base1_addr();
d.print_Base2_addr();

我不明白为什么Derived 中的thisBase1 中的地址相同。这些不是空类,因为它们都包含一个数据成员(数据成员b1i 的地址不同)。好像Base1Derived 重叠。

我忽略了什么?

【问题讨论】:

  • 值相同,但类型不同。
  • Derived 布局大致是[Base1 Base2 i](而不是[i Base1 Base2])。
  • 另一个想法:void print_Base1_addr() const { std::cout &lt;&lt; this &lt;&lt; " " &lt;&lt; &amp;b1 &lt;&lt; '\n'; } 你会注意到成员变量 b1 也与 Base1 对象本身具有相同的地址。

标签: c++ oop inheritance this multiple-inheritance


【解决方案1】:

我不明白为什么 Derived 中的这个地址与 Base1 中的地址相同。

为什么不呢?派生对象包含基类子对象。子对象可以与容器对象具有相同的地址。

内存中的布局大概是这样的:

mem addr   | 0123456789ab # relative to the address of Derived object
Base1      | 1111         # 1 denotes address occupied by Derived::Base1
Base2      |     2222     # 2 denotes address occupied by Derived::Base2
i          |         iiii # i denotes address occupied by Derived::i
Derived    | DDDDDDDDDDDD # D denotes address occupied by Derived
-------------------------
all subobj | 11112222iiii

注意 1 和 D 的开头在地址 0 处是如何重叠的。

好像 Base1 在 Derived 上重叠。

这正是子对象的行为方式。就像数组的元素与整个数组重叠一样,类的成员与类重叠,因此基类的子对象也与派生类的内存重叠。

【讨论】:

    【解决方案2】:

    派生类只是扩展任何基类。最后,都是从同一个地址开始的一个对象。

    在您的示例中,d 是该结果类的一个实例。它将始终具有相同的起始地址。

    【讨论】:

      猜你喜欢
      • 2020-11-25
      • 2012-03-14
      • 2015-03-04
      • 2018-02-25
      • 2019-01-08
      • 1970-01-01
      • 1970-01-01
      • 2013-08-15
      • 1970-01-01
      相关资源
      最近更新 更多