Рассмотрим приведенный ниже код, предназначенный для изучения того, как выполняются вызовы функций-членов и как он соотносится с объектной моделью 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
Я не понимаю, почему? Кто-нибудь может объяснить, пожалуйста?
К вашему сведению: Бьярне Страуструпу написана статья об этом; более конкретно, вы можете обратиться к разделу 4.2 (стр. 373):
https://www.usenix.org/legacy/publications/compsystems/1989/fall_stroustrup.pdf
Спасибо!