Читать «Справочное руководство по C++» онлайн - страница 73

Бьярн Страустрап

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.

R.12.7 Конструкторы и деструкторы

В конструкторах и деструкторах можно вызывать функцию-член. Отсюда следует, что можно вызывать (непосредственно или косвенно) виртуальные функции. Вызываемая функция должна быть определена в классе самого конструктора или деструктора или в базовых классах, но не должна быть функцией, которая их подавляет в производном классе. Этим обеспечивается то, что еще несозданные объекты не будут использованы при выполнении конструктора или деструктора. Рассмотрим пример:

class X {

public:

 virtual void f();

 X() { f(); } // вызов X::f()

 ~X() { f(); } // вызов X::f()

};

class Y: public X {

 int& r;

public:

 void f()

 {

  r++; // беда, если `r' не инициализировано

 }

 Y(int& rr)::r(rr) {}

};

Результат непосредственного или косвенного вызова из конструктора чистой виртуальной функции для инициализируемого объекта неопределен, если только явно не использовано уточнение имени функции (§R.10.3).

R.12.8 Копирование объектов класса

Объекты класса могут копироваться двумя способами: либо присваиванием (§R.5.17), либо инициализацией (§R.12.1, §R.8.4), которая может происходить при передаче параметров (§R.5.2.2) или результата функции (§R.6.6.3). Для класса X эти две операции концептуально реализуются как операция присваивания и конструктор копирования (§R.12.1). В программе можно определить или одну из них, или обе. Если пользователь не определил их в программе, то они будут для всех членов класса X определяться соответственно как присваивание по членам и инициализация по членам.

Если все базовые классы и все члены класса X имеют конструктор копирования, в котором допустимы в качестве параметра объекты типа const, то порождаемый конструктор копирования для X будет иметь единственный параметр типа const X& и записываться так: