成员函数调用和 C++ 对象模型
Member Function Call and the C++ Object Model
考虑以下代码,旨在研究如何进行成员函数调用以及它与 C++ 的对象模型的关系:
struct A {
int a_;
};
struct B : A {
int b_;
void f();
};
void B::f() {
std::cout << "this\t" << std::hex << this << '\n';
}
struct C: B {
int c_;
};
int main()
{
C c;
C* pc = &c;
std::cout << "&c\t" << std::hex << pc << '\n';
pc->f();
return 0;
}
基于 C++ 对象模型,对象 c
将具有对象布局:
-------
| a_ |
|------ |
| b_ |
|------ |
| c_ |
-------
并且,
B::f()
将被翻译成 void f(B *const)
pc->f()
会被翻译成 void f(pc + offset(b_))
,其中 offset(b_)
表示子对象 B
在 c
. 中的偏移量
所以,根据以上观察,输出应该是:
&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
谢谢!
Class C只继承了一个class B。所以你有
struct B
^
|
|
struct C
当创建class C 的对象时,class B 的子对象被放置在为class C 的对象分配的内存的开头.
在 class B 的对象中有一个 class A 的子对象。
你可以想象一下 class C 的对象的放置方式
struct B b;
int c_;
考虑以下代码,旨在研究如何进行成员函数调用以及它与 C++ 的对象模型的关系:
struct A {
int a_;
};
struct B : A {
int b_;
void f();
};
void B::f() {
std::cout << "this\t" << std::hex << this << '\n';
}
struct C: B {
int c_;
};
int main()
{
C c;
C* pc = &c;
std::cout << "&c\t" << std::hex << pc << '\n';
pc->f();
return 0;
}
基于 C++ 对象模型,对象 c
将具有对象布局:
-------
| a_ |
|------ |
| b_ |
|------ |
| c_ |
-------
并且,
B::f()
将被翻译成void f(B *const)
pc->f()
会被翻译成void f(pc + offset(b_))
,其中offset(b_)
表示子对象B
在c
. 中的偏移量
所以,根据以上观察,输出应该是:
&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
谢谢!
Class C只继承了一个class B。所以你有
struct B
^
|
|
struct C
当创建class C 的对象时,class B 的子对象被放置在为class C 的对象分配的内存的开头.
在 class B 的对象中有一个 class A 的子对象。
你可以想象一下 class C 的对象的放置方式
struct B b;
int c_;