成员函数调用和C++对象模型

Member Function Call and the C++ Object Model

本文关键字:对象模型 C++ 函数调用 成员      更新时间:2023-10-16

请考虑以下代码,该代码旨在研究如何进行成员函数调用以及它与C++的对象模型的关系:

struct A {
int a_;
};
struct B : A {
int b_;
void f();
};
void B::f() {
std::cout << "thist" << std::hex << this << 'n';
}
struct C: B {
int c_;
};
int main()
{
C c;
C* pc = &c;
std::cout << "&ct" << std::hex << pc << 'n';
pc->f();
return 0;
}

根据C++对象模型,对象c将具有对象布局:

-------
| a_    |
|------ |
| b_    |
|------ |
| c_    |
-------

  1. B::f()将被翻译成void f(B *const)
  2. pc->f()将被转换为void f(pc + offset(b_)),其中offset(b_)表示子对象Bc中的偏移量。

因此,基于上述观察结果,输出应为:

&c     address_of_c
this   address_of_c + sizeof(a_) = address_of_c + 4

但是我得到的是两者的相同地址(我使用的是g ++ 9.2(:

&c      0xffffcc0c
this    0xffffcc0c

我不清楚为什么?有人可以解释一下吗?

仅供参考:Bjarne Stroustrup有一篇关于这个的文章;更具体地说,你可以参考第4.2节(第373页(:

https://www.usenix.org/legacy/publications/compsystems/1989/fall_stroustrup.pdf

谢谢!

类C 只继承一个类 B。所以你有

struct B
^
|
|
struct C

创建类 C 的对象时,类 B 的子对象被放置在为类 C 的对象分配的内存的开头。

在类 B 的对象中,有一个类 A 的子对象。

您可以按以下方式想象 C 类对象的放置

struct B b;
int c_;