1) Да, сначала создаются базы, затем нестатические члены-данные, затем вызывается конструктор производного класса.Причина в том, что код в конструкторе этого класса может видеть и использовать полностью построенную базу.
2) Да.Вы можете понимать это буквально: в памяти, назначенной объекту производного класса, есть область, называемая «подобъектом базового класса».Объект производного класса «содержит» подобъект базового класса точно так же, как он содержит подобъекты-члены для любых нестатических членов-данных.На самом деле, пример, приведенный в вопросе, является частным случаем: «оптимизация пустого базового класса».Этому подобъекту базового класса разрешается быть нулевым размером, хотя полные объекты типа base
никогда не имеют нулевого размера.
Это ограничение, однако, вещь низкого уровня.Это верно, поскольку другие говорят, что концептуально базы отличаются от членов, и синтаксис и семантика языка трактуют их по-разному, даже если сами подобъекты являются всего лишь частями макета класса.
3) Это деталь реализации.Код в теле конструктора базового класса выполняется перед кодом в теле конструктора производного класса, и в действительности конструктор производного класса затем выполняется в невидимом сгенерированном компилятором блоке try / catch, чтобы гарантировать, что если он выбрасываетбазовый класс разрушен.Но это зависит от компилятора, как добиться этого с точки зрения того, что фактически делают точки входа функции в выдаваемом коде.
Когда у класса есть виртуальные базы, обычно конструктор приводит к тому, что два разных тела функции являютсяemitted - один для использования, когда этот класс является наиболее производным типом, и один для использования, когда этот класс сам является базовым классом.Причина в том, что виртуальные базовые классы создаются самым производным классом, чтобы гарантировать, что когда они используются совместно, они создаются только один раз.Таким образом, первая версия конструктора будет вызывать все конструкторы базового класса, тогда как вторая версия будет вызывать конструкторы только для не виртуальных баз.
Компилятор всегда «знает», какие базы имеет класс, потому что вы можете толькосоздать объект полного типа, который подразумевает, что компилятор может видеть определение класса, и который определяет основы.Таким образом, не возникает вопроса только о «обнаружении, что у него есть базовый класс», когда вводится конструктор - компилятор знает , что у него есть базовый класс, и если вызов конструктора базового класса находится внутрипроизводный код конструктора класса, это просто для удобства компилятора.Он может генерировать вызовы конструкторов базового класса в каждом месте, где вы создаете объект, и в этом отношении в случаях, когда конструктор производного класса может быть и встроен, это конечный эффект.