Виртуальные таблицы методов

При обсуждении запечатанных классов довольно часто упоминается термин "виртуальная таблица функций". Что именно это? Некоторое время назад я читал о таблице методов (я тоже не помню цель этой цели), и google/поиск здесь дает результаты, связанные с С++.

Спасибо


person GurdeepS    schedule 09.03.2010    source источник


Ответы (3)


Таблица виртуальных функций C# работает в основном так же, как таблица C++, поэтому любые ресурсы, описывающие, как работает таблица виртуальных функций C++, должны помочь вам и с таблицей C#.

Например, описание из Википедии неплохое.

person Dean Harding    schedule 09.03.2010
comment
Обычно ответы должны быть автономными и не должны быть связаны с каким-либо третьим текстом... особенно со статьей в Википедии... - person Marine Galantin; 11.02.2021

«Виртуальная таблица функций» или «виртуальная таблица методов» — это список указателей на методы, которые есть у каждого класса. Он содержит указатели на виртуальные методы класса.

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

Если у вас, например, есть ссылка объекта на строку:

object obj = "asdf";

и вызовите виртуальный метод ToString:

string text = obj.ToString();

он будет использовать метод String.ToString, а не метод Object.ToString. Он использует таблицу виртуальных методов класса String (на которую указывает указатель в экземпляре строки), а не таблицу виртуальных методов класса Object.

person Guffa    schedule 09.03.2010
comment
Правильно ли я понимаю, что таблица методов создается для любого типа. Таким образом, этот тип значения также имеет таблицу методов. И еще один вопрос, как тип узнает, что у него есть таблица методов? Хранится ли таблица методов или на нее ссылаются в объекте-типе? Но тип значения не имеет указателя типа-объекта. :/ Вот связанный вопрос: stackoverflow.com/questions/35185528/ - person Anton Lyhin; 03.02.2016
comment
@Spirit: Да, у каждого типа есть таблица методов (по крайней мере, в той или иной форме на каком-то этапе). Поскольку вызовы типов значений не являются виртуальными, точные методы определяются во время компиляции, поэтому им не нужна таблица виртуальных методов, для них она должна существовать только в исполняемом файле для целей отражения. Я не знаю, где на самом деле хранятся таблицы методов, это будет зависеть от реализации, поэтому вы должны искать в исходном коде фреймворка для этого (однако эта часть реализации может быть не общедоступной). - person Guffa; 05.02.2016
comment
Спасибо. Ваш ответ очень ясен. Наконец-то я нашел похожее обсуждение SO: stackoverflow.com/questions/926352/ - person Anton Lyhin; 06.02.2016
comment
Код IL для string text = obj.ToString();: callvirt instance string [mscorlib]System.Object::ToString(), поэтому кажется, что на самом деле он не использует String.ToString. - person OfirD; 30.08.2016
comment
@HeyJude Объект obj во время компиляции — это объект. Поскольку ToString является виртуальным, а объект является ссылочным типом, вызов будет происходить с помощью ключевого слова callvirt. Callvirt вызовет String.ToString() после просмотра таблицы виртуальных методов экземпляра obj. Может показаться, что он не будет вызывать String.ToString, но на самом деле это так. - person Noel Widmer; 24.01.2017
comment
Содержатся ли невиртуальные методы в виртуальной таблице или для них существует отдельная таблица невиртуальных методов? @Гуффа - person Claude Tan; 24.08.2017

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

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

person Fadrian Sudaman    schedule 09.03.2010