R Справочное руководство по С++

R.12.6.2 Инициализация членов и базовых классов.

   


Назад  |  Вперёд

В определении конструктора можно задать инициализацию прямых базовых классов и членов, не наследуемых из базовых классов. Это особенно полезно для тех объектов, констант и ссылок, для которых различаются семантики присваивания и инициализации. Конструкция инициализатор-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.


Назад  |  Вперёд


OtDiatlovaOU
К началу книги

Оформление и дизайн книги OtDiatlovaOU.
Вся книга, архив.