2010-11-21 5 views
4

Я знаю, что, как реализовать разрешение вызова виртуальных функций, не является частью stand-by C++, ни он ничего не говорит о vptr или v-table, но позвольте мне задать этот вопрос здесь.Когда v-таблица создана для класса?

Я слышал, что v-таблица является общей методикой, используемой компиляторами для реализации разрешения вызова виртуальных функций. Мое недопонимание в этом заключается в том, что для каждого класса требуется только виртуальная таблица.

Что мне интересно, когда v-таблица создана для класса?
Это когда класс заданного типа (который требует v-таблицы) создается в пространстве процессов в первый раз?
Все остальные впоследствии созданные объекты этого типа в этом пространстве процесса ссылаются на уже созданную v-таблицу?
Когда этот v-стол будет удален?

Прошу прощения, если это слишком субъективный или дискуссионный вопрос, но эти вопросы задерживаются у меня на некоторое время, и я чувствую, что его спрашивают здесь.

+0

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

+0

Если вас интересуют детали реализации, вы должны поместить [Внутри объектной модели C++] (http://www.amazon.com/dp/0201834545/) в свой список пожеланий на Рождество. Он подробно описывает vtables и другие материалы. – fredoverflow

+0

Хорошо, это может быть статическая таблица, не связанная со временем жизни объектов, имеет смысл. – riderchap

ответ

7

V-таблица статически выделена и никогда не удаляется и не выделяется явно. Указатели в любом конкретном конкретном объекте являются константами.

+0

Ну, это просто неправда. Любой объект в DLL или разделяемой библиотеке не может знать адрес функций до тех пор, пока он не будет загружен в память, так как vtables должен быть сконструирован во время выполнения, поэтому значения могут быть постоянными после загрузки, но они не являются по-настоящему постоянными, как в константы времени компиляции. –

+0

@Martin York: vtables создаются во время компиляции компилятором, который скомпилировал все связанные с ними, и который вставляет постоянные указатели в эти слоты.Адрес функций может не быть известен компилятору dll, но они известны тем, что связано с ним. Дело в том, что весь процесс происходит во время компиляции. Единственное, что происходит во время выполнения, - это следовать указателю. – Puppy

+2

Как это может произойти во время компиляции, когда вы не знаете адрес методов до выполнения. Даже компоновщик не знает адрес метода, когда он находится в dll. DLL можно загружать в любом месте в памяти, поэтому адреса не могут быть известны до тех пор, пока не будет загружена dll (это операции во время выполнения). Даже если вы попытаетесь восстановить базу данных dll, чтобы попытаться дать им явные адреса, компилятор не может гарантировать эти адреса (поскольку другая dll может вручную загружать данные в это адресное пространство и тем самым принудительно сдвигать dll). –

1

Vtable - это статические данные, доступные сразу при загрузке. BTW, он обычно содержится в блоке компиляции, который содержит определение первой неиннижной виртуальной функции в классе (и эта эвристика приводит к проблеме, когда есть только одна виртуальная функция, которая является встроенной).

0

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

4

C++ FAQ обеспечивает упрощенное объяснение механизма vtable. Вы должны прочитать его, хотя вам, возможно, придется подробно ознакомиться с вашей конкретной документацией компилятора.

Наиболее важные идеи с моей точки зрения:

  • виртуальные таблицы для типа статична и построен во время компиляции
  • Каждый из экземпляров типа содержит указатель к этой таблице
  • Поскольку этот указатель инициализируется во время построения, виртуальная функция-член никогда не должна вызываться из конструктора
+0

. Функция виртуального члена может быть вызвана из конструктора. Почему его не следует называть? –

+0

http://www.artima.com/cppsource/nevercall.html – icecrime

+0

Да, вы можете вызывать виртуальные методы из конструктора, но вы должны знать, какой именно метод будет вызываться. В общем случае я согласен с правилом «не вызывайте виртуальные методы из конструктора/деструктора», но один размер не подходит для всех. –