Вызов функции-члена и объектная модель C ++ - PullRequest
1 голос
/ 16 февраля 2020

Рассмотрим приведенный ниже код, предназначенный для изучения того, как выполняются вызовы функций-членов и как он соотносится с объектной моделью 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_    |
  -------

И,

  1. B::f() будет переведен в void f(B *const)
  2. 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

Спасибо!

1 Ответ

1 голос
/ 17 февраля 2020

Класс C наследует только один класс B. Таким образом, у вас есть

struct B
   ^
   |
   |
struct C

Когда был создан объект класса C, подобъект класса B был помещен в начало память, выделенная для объекта класса C.

Внутри объекта класса B есть подобъект класса A.

Вы можете представить размещение объект класса C следующим образом

struct B b;
int c_;
...