2012-03-04 2 views
-2

Некоторые вопросы относительно наследования C++:C++ когда выполняется базовый конструктор?

В каком порядке выполнен код базовых конструкторов?

Есть ли способ повлиять на этот заказ? (например, другие языки позволяют размещать «super()» где-то внутри конструктора)

Можно ли получить доступ к защищенным членам базовых классов в конструкторе?

+1

Добавьте 'std :: cout' каждому конструктору и узнайте. –

+0

Это ваша домашняя работа? Вы пробовали читать книгу? – littleadv

+0

nope - попытка перенести некоторый код, который зависит от этого – Mat

ответ

1

Предположим, что класс A имеет базовые классы B_i, все конструкторы B_i выполняются до выполнения любого из кода для конструктора A. Единственное исключение - это когда вы инициализируете базовый класс конструктором не по умолчанию, но как только они запускаются, все базовые классы выполняются, и в любом случае они должны идти первым в списке инициализации. Хорошо получить доступ к защищенным членам базовых классов, потому что базовый класс уже сконструирован.

Например:

class A : public B, C { 
    A() 
    : B(1), //B and C are now constructed 
    memberOfA(memberOfB) 
    { 
    } 
}; 

Если член memberOfA нужно что-то из B называется memberOfB то это нормально, потому что B уже построен.

+0

ok - так, если базовые классы инициализируются конструктором, отличным от стандартного, этот код конструктора, отличный от стандартного, выполняется после кода конструктора A (не по умолчанию)? – Mat

+0

Предложение о «исключении» меня сбивает с толку, и я не понимаю, что это неправильно. Кроме того, порядок конструкторов родительского класса в списке инициализаторов _irrelevant_ в порядке построения. Они построены в том порядке, в котором они получены в декларации класса. –

+1

@ Мать родительских классов инициализируется в том порядке, в котором они объявлены в классе, а затем члены в том порядке, в котором они объявлены в классе. Затем выполняется тело конструктора класса. Инициализатор наименее говорит _how_ для инициализации, а не _when_ (это не влияет на порядок, когда-либо). –

0

Конструктор «родительского»/суперкласса всегда называется первым. Это истинно рекурсивно в случае множественного наследования. (И это одна из причин, по которой вам действительно не нужны виртуальные конструкторы поведения на C++;)) Что касается доступа к членам суперкласса: это прекрасно, они инициализируются.

+0

Ответ в основном правильный, но подразумевает, что множественное наследование - это то, где «суперкласс» происходит от третьего класса, а не где класс, о котором идет речь, наследуется от нескольких классов. –

1

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

Невозможно повлиять на порядок, в котором происходит строительство, и безопасно получить доступ к элементам базы в конструкции производного типа. Вероятно, удивительно, что в противоположном направлении вызов виртуальной функции из базового конструктора. На каждом этапе процесса строительства изменяется тип объекта. То есть, заданный объект типа X с базами B_i, только после того, как все подобъекты B_i завершили и прямо до того, как первый член X начнет, тип объекта станет X. Импликацией этого является то, что вызов виртуального метода в базе класс будет отправлен в этот базовый класс, а не на конечный тип, который будет сконструирован.

+0

"только после всех подобъектов B_i ... тип объекта становится X" Не верно. Объект имеет тип 'X', когда его конструктор имеет * завершен *. Не просто построил свои базы и элементы, но также выполнил тело самой функции конструктора. До тех пор это еще не «Х». –

+0

@NicolBolas: Я так не думаю. Стандарт четко указывает, что вы можете вызывать виртуальные функции-члены в конструкторе и * mem-initializer * s членов данных и что вызов будет отправлен в класс вызываемого конструктора. В нем также указано, что в этот момент * typeid * будет возвращать объект * type_info *, относящийся к типу класса, который в настоящее время строится. Это действительно * выглядит *, как в этой конкретной точке, тип объекта - это тип, который строится (12.7/4,5). –

+0

Хорошо, рассмотрим это [ГОТВ о строительстве объекта и жизни объекта] (http://www.gotw.ca/publications/mill13.htm). Кажется, это не согласуется. –

Смежные вопросы