Здравствуйте, Sm0ke, Вы писали:
S>Возможно в конструкторах класса с vtable есть какой-то дополнительный исполняемый код
Ну да, первым полем в любом конструкторе неявно инициализируется указатель на vtable.
При вызове всех конструкторов по цепочке от базы к наследникам это поле многократно перезаписывается (с точностью до оптимизации, если компилятор может инлайнить конструкторы — это почему конструкторы базовых классов лучше делать инлайными, дабы попытаться исключить многократную перезапись указателя на vtable в большинстве случаев).
S>но его-же можно добавить и при структурной инициализации ...
Ситуация наоборот — у объекта с виртуальными методами должен быть конструктор (хотя бы, по-умолчанию), иначе объект этого типа невозможно создать.
А если есть конструктор, то невозможна структурная инициализация.
Если в этом коде раскомментировать виртуальный метод, то как создать Derived? ))
struct Base {
int a;
int b;
//Base(int a, int b) : a(a), b(b) {}
//virtual void f() {}
};
struct Derived : Base {
int c;
//Derived(const Base & b, int c)
// : Base(b), c(c) {}
};
int main() {
Derived obj { {42, 43}, 44 };
std::cout << obj.a << ", " << obj.b << ", " << obj.c << std::endl;
}
(пусть даже не через структурную инициализацию, а хоть как-нибудь?)
А если определить конструктор — прощай структурная инициализация.

Благо, в современном единообразном синтаксисе вызова конструкторов и структурной инициализации можно добавлять конструкторы, не меняя код в местах инициализации объектов (раскомментировать всё в сниппете, можно поочерёдно сверху, наблюдая совместную жизнь в одном синтаксисе вызовов конструкторов и структурной инициализации).