2010-10-03 5 views
9

Я хотел бы знать, когда создается vtable? Независимо от того, находится ли он в стартовом коде перед main() или в какой-то другой момент времени?Когда создается VTable в C++?

ответ

11

A vtable не является концепцией C++, поэтому, если они используются и когда они созданы, если они используются, это будет зависеть от реализации.

Как правило, vtables - это структуры, созданные во время компиляции (поскольку они могут быть определены во время компиляции). Когда объекты определенного типа создаются во время выполнения, они будут иметь vptr, который будет инициализирован для указания на статическом vtable во время строительства.

+0

Спасибо, Но один из моих инструкторов сказал мне, что перед вызовом основной функции создается виртуальная таблица. Он создается во время кода StartupCRT. Я просто хотел подтвердить это и больше узнать об этом. – Sen

+4

@ Сен: Возможно, но, возможно, нет. Реализации C++ не нужно использовать _vtables_, поэтому они встроены в двоичный код, созданный в код запуска или динамически выделяемый при необходимости (маловероятно) полностью зависит от реализации. Независимо от того, какая реализация хочет сделать, должна быть прозрачной для программы, поэтому важно, чтобы программист знал, какое поведение следует ожидать от использования виртуальных функций, чем то, как они реализованы на той конкретной платформе, которую он использует. –

+1

@Sen: StartupCRT звучит очень похоже на специфику Microsoft, и то, что он или она вам сказал, вполне может быть правдой для Visual C++ Microsoft, но, как говорит Чарльз, сам стандарт C++ позволяет каждому поставщику компилятора выбрать любую реализацию, которая им нравится, как долго так как он работает правильно. У других поставщиков, вероятно, даже не будет функции «StartupCRT». – user433534

3

vtable создается во время компиляции. Когда во время выполнения создается новый объект, скрытый указатель vtable устанавливается на vtable.

Имейте в виду, что вы не можете надежно использовать, если виртуальные функции пока объект полностью не сконструирован. (Нет вызывающих виртуальных функций в конструкторе.)

EDIT Я думал, что рассмотрю вопросы в комментариях.

Как уже указывалось, точные детали того, как создается и используется виртуальная таблица, остаются в стороне от реализации. Спецификация C++ предоставляет только определенные типы поведения, которые должны быть гарантированы, поэтому для реализации существует множество возможностей для маневра. Он не должен использовать vtables вообще (хотя большинство из них). Как правило, вам не нужно знать эти детали. Вам просто нужно знать, что когда вы вызываете виртуальную функцию, она делает то, что вы ожидаете, независимо от , как это делает.

При этом я уточню пару моментов о типичной реализации. Класс с виртуальными функциями имеет скрытый указатель (мы будем называть vptr), который указывает на таблицу vtable для этого класса. Предположим, у нас есть класс сотрудника:

class Employee { 
public: 
    virtual work(); 
}; 

Этот класс будет иметь vptr в его структуру, так что на самом деле может выглядеть следующим образом:

class Employee { 
public: 
    vtble *vptr; // hidden pointer 
    virtual work(); 
}; 

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

+3

Строго говоря, использование виртуальных функций в конструкторе является надежным. Результат хорошо определен (кроме чистых виртуальных функций), но обычно не тот, который желателен. –

+0

Привет, JoshD. Не могли бы вы объяснить следующую строку, которую вы сказали: «Когда во время выполнения создается новый объект, скрытый указатель vtable устанавливается на vtable». Поскольку я новичок, мне трудно понять это. – Sen

+1

Чарльз прав, но на самом деле неплохо иметь общее ожидание того, что на самом деле делают компиляторы - пока вы не слишком полагаетесь на него - и ваше описание реалистично. @Sen: если вы говорите «Employee e', где Employee - класс с виртуальными методами, то новый объект e обычно имеет пространство, зарезервированное компилятором для указателя на vtable для Employee. Если бы у вас был президент из Employee, то его указатель vtable указывал бы на vtable v Президента, но оба указателя vtable будут иметь одинаковую величину по сравнению с другими членами данных Employee. – user433534

Смежные вопросы