为什么 "this" 指针在派生和第一个基数中具有相同的值 class
Why "this" pointer has same value inside derived and first base class
考虑这些 类 作为基础 类:
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
继承自Base1
和Base2
:
struct Derived: Base1, Base2 {
int i;
void print_addr() const { std::cout << this << '\n'; }
};
然后此代码在 Derived
和 Base1
中为 this
打印相同的地址,但在 Base2
中不打印:
Derived d{};
d.print_addr();
d.print_Base1_addr();
d.print_Base2_addr();
我不明白为什么 Derived
中的 this
与 Base1
中的地址相同。它们不是空的 类,因为它们都包含一个数据成员(数据成员的地址 b1
和 i
不同)。就好像 Base1
重叠在 Derived
.
上
我忽略了什么?
I don't understand why this in Derived has the same address as in Base1.
为什么不呢?派生对象包含基础 class 子对象。子对象可以与容器对象具有相同的地址。
内存中的布局大概是这样的:
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 重叠。
It is as if Base1 overlaps on the Derived.
这正是子对象的行为方式。就像数组的元素与整个数组重叠一样,class 的成员与 class 重叠,因此基础 class 子对象也与派生 class 的内存重叠。
派生 classes 只是扩展任何基础 classes。最后,所有对象都从同一地址开始。
在您的示例中,d
是结果 class 的一个实例。它将始终具有相同的起始地址。
考虑这些 类 作为基础 类:
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
继承自Base1
和Base2
:
struct Derived: Base1, Base2 {
int i;
void print_addr() const { std::cout << this << '\n'; }
};
然后此代码在 Derived
和 Base1
中为 this
打印相同的地址,但在 Base2
中不打印:
Derived d{};
d.print_addr();
d.print_Base1_addr();
d.print_Base2_addr();
我不明白为什么 Derived
中的 this
与 Base1
中的地址相同。它们不是空的 类,因为它们都包含一个数据成员(数据成员的地址 b1
和 i
不同)。就好像 Base1
重叠在 Derived
.
我忽略了什么?
I don't understand why this in Derived has the same address as in Base1.
为什么不呢?派生对象包含基础 class 子对象。子对象可以与容器对象具有相同的地址。
内存中的布局大概是这样的:
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 重叠。
It is as if Base1 overlaps on the Derived.
这正是子对象的行为方式。就像数组的元素与整个数组重叠一样,class 的成员与 class 重叠,因此基础 class 子对象也与派生 class 的内存重叠。
派生 classes 只是扩展任何基础 classes。最后,所有对象都从同一地址开始。
在您的示例中,d
是结果 class 的一个实例。它将始终具有相同的起始地址。