Что такое виртуальная таблица (Virtual Table / vtable) в контексте ООП?

«Что такое виртуальная таблица (Virtual Table / vtable) в контексте ООП?» — вопрос из категории ООП, который задают на 22% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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

Как это работает:

  1. Для каждого класса компилятор создаёт свою vtable, содержащую адреса всех его не-final методов.
  2. Каждый экземпляр класса содержит скрытый указатель (isa в Objective-C) на структуру класса, которая, в свою очередь, содержит vtable.
  3. При вызове метода (например, object.method()) runtime следует по этому указателю, находит в vtable адрес нужной функции и вызывает её.

Пример на Swift:

class Animal {
    func makeSound() { print("Some sound") } // Попадёт в vtable
}

class Dog: Animal {
    override func makeSound() { print("Woof!") } // Переопределяет запись в vtable
}

class Cat: Animal {
    override func makeSound() { print("Meow!") }
    final func purr() { print("Purr") } // НЕ попадёт в vtable, вызов статический
}

let animals: [Animal] = [Dog(), Cat()]
for animal in animals {
    animal.makeSound() // Динамический вызов через vtable: "Woof!", затем "Meow!"
}

Отличия и оптимизации в Swift:

  • Структуры и перечисления (value types) не используют vtable. Вызовы их методов разрешаются статически во время компиляции, что быстрее.
  • Ключевое слово final у класса или метода исключает его из механизма vtable, позволяя компилятору использовать статическую диспетчеризацию и проводить агрессивные оптимизации.
  • dynamic диспетчеризация (например, для совместимости с Objective-C или Key-Value Observing) использует другой, более медленный механизм (objc_msgSend).