|
|
В определении конструктора можно задать инициализацию прямых базовых классов и членов, не наследуемых из базовых классов. Это особенно полезно для тех объектов, констант и ссылок, для которых различаются семантики присваивания и инициализации. Конструкция инициализатор-ctor имеет вид
инициализатор-ctor:
: список-инициализаторов-членов
список-инициализаторов-членов:
инициализатор-члена
инициализатор-члена , список-инициализаторов-члена
инициализатор-члена:
полное-имя-класса ( список-выражений opt )
идентификатор
Список параметров используется для инициализации нестатических членов или объектов базового класса. Это единственный способ инициализации нестатических членов, являющихся ссылками или объектами типа const, например:
struct B1 { B1(int); /* ... */ }; struct B2 { B2(int); /* ... */ }; struct D : B1, B2 { D(int); B1 b; const c; }; D::D(int a) : B2(a+1), B1(a+2), c(a+3), b(a+4) { /* ... */ } D d(10);
В начале инициализируются базовые классы в порядке их описания
(независимо от порядка инициализаторов-членов), затем по той же
схеме инициализируются члены, и наконец выполняется тело D::D()
($$R.12.1). Порядок описания выдерживается для того, чтобы гарантировать,
что вложенные объекты и члены будут уничтожаться в порядке, обратном
их инициализации.
Особый случай представляют виртуальные базовые классы. Они создаются
прежде, чем любой невиртуальный базовый класс и в том же порядке,
в каком появляются при обходе снизу и слева-направо ацикличного
направленного графа базовых классов. Порядок "слева-направо" - это
тот, в котором имена базовых классов задаются при описании в
производном классе.
Полным называется объект, который не является вложенным объектом,
представляющим некоторый базовый класс. Класс такого объекта
называют наибольшим производным классом объекта. Все вложенные
объекты виртуальных базовых классов инициализируются с помощью
конструктора наибольшего производного класса. Если в конструкторе
наибольшего производного класса не задан инициализатор-члена для
виртуального базового класса, тогда этот виртуальный базовый класс
должен иметь стандартный конструктор,либо не иметь никакого
конструктора. Всякий инициализатор-члена для виртуального базового
класса, заданный не в конструкторе класса полного объекта, игнорируется.
Приведем пример:
class V { public: V(); V(int); // ... }; class A : public virtual V { public: A(); A(int); // ... }; class B : public virtual V { public: B(); B(int); // ... }; class C : public A, public B, private virtual V { public: C(); C(int); // ... }; A::A(int i) : V(i) { /* ... */ } B::B(int i) { /* ... */ } C::C(int i) { /* ... */ } V v(1); // use V(int) A a(2); // use V(int) B b(3); // use V() C c(4); // use V()
Инициализатор-члена вычисляется в области видимости конструктора, в котором он появился. Например, в следующем фрагменте
class X { int a; public: const int& r; X()::r(a) { } };
X::r инициализируется для каждого объекта класса X ссылкой на X::a.
| |