C++ вопросы о Inheritance/VTable

Это работало на меня (в Windows Subsystem для Linux, Ubuntu):

npm install puppeteer

sudo apt-get install gconf-service libasound2 libatk1.0-0 libatk-bridge2.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget

список Зависимости от: https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md#chrome-headless-doesnt-launch-on-unix

10
задан Alex B 5 September 2009 в 17:00
поделиться

4 ответа

Если вы объявляете виртуальные функции, вы также должны объявить свой деструктор виртуальным; -).

  1. B имеет виртуальную таблицу, потому что у нее есть виртуальная функция, а именно func0 () . Если вы объявляете функцию (включая деструктор) виртуальной в базовом классе, все его производные классы также будут иметь функцию с такой же виртуальной подписью. И это приведет к тому, что у них будет vtable. Более того, B будет иметь vtable, даже если вы не объявили в ней func0 явно.

  2. Не виртуальные функции не упоминаются через vtables.

  3. См. 2.

  4. Нет. Таблицы классов создаются на основе объявлений классов. Тела функций класса (не говоря уже о других функциях) не учитываются. Следовательно, B имеет vtable, потому что его функция func0 () виртуальная.

Есть еще одна хитрая деталь, хотя не в этом суть вашего вопроса. Вы объявили свою функцию B :: func0 () встроенной. В компиляторе gcc , если виртуальная функция объявлена ​​встроенной, она сохраняет свой слот в виртуальной таблице, причем слот указывает на специальную функцию, созданную для этой встроенной (которая считается принятием ее адреса, что делает встроенную испускается). Это означает, что то, является ли функция встроенной, не влияет на количество слотов в vtable и ее необходимость в классе.

слот, указывающий на специальную функцию, создаваемую для этой встроенной функции (которая считается принятием ее адреса, что делает ее встроенной). Это означает, что то, является ли функция встроенной, не влияет на количество слотов в vtable и ее необходимость в классе.

слот, указывающий на специальную функцию, создаваемую для этой встроенной функции (которая считается принятием ее адреса, что делает ее встроенной). Это означает, что то, является ли функция встроенной, не влияет на количество слотов в vtable и ее необходимость в классе.

19
ответ дан 3 December 2019 в 15:35
поделиться
  1. Да, потому что его базовый класс имеет один; также его деструктор является виртуальным (даже если вы не объявили его виртуальным), потому что деструктор базового класса является виртуальным.

  2. Нет

  3. Нет.

  4. Нет. На самом деле я не думаю, что текущий код является законным: компилятор вызовет деструктор A после того, как он вызовет деструктор B, даже если вы явно не вызываете ~ A из ~ B; поэтому я не думаю, что вам следует вызывать ~ A из ~ B, даже если компилятор позволяет вам.

5
ответ дан 3 December 2019 в 15:35
поделиться

Ссылаясь на обновленный пример:

  1. Да, b имеет vtable. Обратите внимание, что b :: func0 () является виртуальным (переопределяет a :: func0 ()), хотя вы явно не пометили его как виртуальный. Странная "лазейка" C ++, я думаю.
  2. Нет. Невиртуальные функции не находятся в vtable.
  3. См. 2.
  4. Нет. Вы переопределили: func0 (); не имеет значения, вызываете вы :: func0 () или нет.

Несколько дополнительных примечаний (зависит от компилятора, но это довольно распространенные обобщения):

  • Каждый экземпляр b будет есть указатель на vtable, потому что вы производны от класса, который имеет виртуальные функции.
  • Это будет иметь место , даже если вы не определили b :: func0 () .
  • В этой ситуации компилятор может иметь экземпляры b , указывающие на статическую vtable a , или он может создать статическую vtable для b и заполнить ее указателями на указатели на члены а .
  • Но по-прежнему требуется , чтобы вы могли правильно получить доступ к экземпляру b через указатель на a .
3
ответ дан 3 December 2019 в 15:35
поделиться
  • Если функция базового класса виртуальная, то если вы переопределите эту функцию в производном классе, она будет неявно виртуальной, даже если вы не укажете явно. Если у класса есть виртуальная функция, то у него есть таблица av.
  • В vtable присутствуют только виртуальные функции, function1 не будет находиться в vtable
  • function2 не будет находиться в vtable по той же причине, что и выше
  • Создание vtable не зависит от вызываете ли вы эту функцию из базового класса или откуда-то еще. Вызов функции не определяет создание vtable.
1
ответ дан 3 December 2019 в 15:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: