C++ 成员函数调用和C++;对象模型
考虑以下代码,这些代码旨在研究成员函数调用的方式以及它与C++对象模型的关系:C++ 成员函数调用和C++;对象模型,c++,class,inheritance,this,C++,Class,Inheritance,This,考虑以下代码,这些代码旨在研究成员函数调用的方式以及它与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* p
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;
}
以及
B::f()
将被转换为void f(B*const)
pc->f()
将转换为void f(pc+offset(b_))
,其中offset(b_)
表示c
中子对象b
的偏移量&c address_of_c
this address_of_c + sizeof(a_) = address_of_c + 4
但我得到的是两者的相同地址(我使用的是g++9.2):
我不清楚为什么?有人能解释一下吗
仅供参考:比亚恩·斯特劳斯特鲁普写了一篇关于这方面的文章;更具体地说,您可以参考第4.2节(第373页):
谢谢 类C只继承一个类B。因此
struct B
^
|
|
struct C
创建类C的对象时,类B的子对象被放置在为类C的对象分配的内存的开头
在B类的对象中有a类的子对象
您可以想象C类对象的放置方式如下
struct B b;
int c_;
为什么您认为它应该是
pc+offset(b)
而不是pc+offset(b)
,即C
中b
子对象的偏移?如果查看图形,您可以看到A
和B
子对象都从顶部开始,与C
对象的地址相同。请注意,链接中的示例不同。它允许C
从A
和B
继承。C中B子对象的偏移量是[u C+sizeof(A_u)=地址[u of_C+4=偏移量(B_u)。在比亚恩的例子中,C从A和B继承。但这有什么关系呢?在你的例子中,A
子对象是B
子对象的一部分,因此B
子对象以a_
开头,而不是以B_
开头。在比亚恩的例子中,情况并非如此,A
和B
子对象是C
的不同部分。
struct B
^
|
|
struct C
struct B b;
int c_;