Когда vptr (указывающий на vtable) инициализируется для полиморфного класса? - PullRequest
6 голосов
/ 06 июля 2011

Это не о "Когда создается VTABLE?" .Скорее, когда VPTR должен быть инициализирован?Это в начале / конце конструктора или до / после конструктора?

A::A () : i(0), j(0)  -->> here ?
{
  -->> here ?
  //...
  -->> here ?
}

Ответы [ 3 ]

16 голосов
/ 06 июля 2011

Механизм для виртуальных вызовов (обычно это v-таблица, но не обязательно) настраивается во время ctor-initializer , после построения базовых подобъектов и до построения членов.Раздел [class.base.init] постановляет:

Функции-члены (включая виртуальные функции-члены, 10.3) можно вызывать для строящегося объекта.Точно так же строящийся объект может быть операндом оператора typeid (5.2.8) или dynamic_cast (5.2.7).Однако, если эти операции выполняются в ctor-initializer (или в функции, вызываемой прямо или косвенно из ctor-initializer ) перед всеми mem-initializer если базовые классы завершены, результат операции не определен.

На самом деле, во время построения базовых подобъектов существует механизм виртуальных функций, но он настроен для базового класса.В разделе [class.cdtor] говорится:

Функции-члены, включая виртуальные функции (10.3), могут вызываться во время создания или уничтожения (12.6.2).Когда виртуальная функция вызывается прямо или косвенно из конструктора или деструктора, в том числе во время создания или уничтожения нестатических членов-данных класса, и объект, к которому применяется вызов, является объектом (назовите его x)в процессе конструирования или уничтожения вызываемая функция является окончательным переопределением в классе конструктора или деструктора, а не переопределением его в более производном классе.Если вызов виртуальной функции использует явный доступ к члену класса (5.2.5) и выражение объекта относится к полному объекту x или одному из подобъектов базового класса этого объекта, но не к x или одному из его подобъектов базового класса,поведение не определено.

2 голосов
/ 06 июля 2011

инициализируется между конструкторами базового и производного классов:

class Base { Base() { } virtual void f(); };
class Derived { Derived(); virtual void f(); };

Это происходит, когда необработанная память преобразуется в базовый объект.Это происходит, когда базовый объект преобразуется в производный объект во время создания объекта.То же самое происходит в обратном порядке при уничтожении объекта.Т.е. каждый раз, когда тип меняется, указатель vtable меняется.(Я уверен, что кто-то комментирует, что vtables не должен существовать согласно стандарту ..)

...