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

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

 void operator delete(void*);

};

struct D: B {

 ~D();

 void* operator new(size_t);

 void operator delete(void*);

};

void f()

{

 B* p = new D;

 delete p;

}

В этом примере память для объекта класса D выделяется с помощью D::operator new(), а благодаря наличию виртуального деструктора, освобождается с помощью D::operator delete().

R.12.6 Инициализация

Объект класса без конструкторов, без частных или защищенных членов, без виртуальных функций и без базовых классов можно инициализировать с помощью списка инициализаторов (§R.8.4.1). Объект класса с конструктором должен инициализироваться или иметь стандартный конструктор (§R.12.1). Стандартный конструктор используется для объектов, которые не проходят явной инициализации.

R.12.6.1 Явная инициализация

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

class complex {

 //…

public:

 complex();

 complex(double);

 complex(double,double);

 //…

};

complex sqrt(complex,complex);

complex a(1); // инициализация вызовом

  // complex(double)

complex b = a; // инициализация копированием `a'

complex c = complex(1,2); // конструктор complex(1,2)

  // вызывается complex(double,double)

  // и копируется в `c'

complex d = sqrt(b,c); // вызывается sqrt(complex,complex),

  // результат копируется в `d'

complex e; // инициализация вызовом конструктора

complex f = 3; // complex(3), вызывается

  // complex(double) и результат

  // копируется в `f'

Перегрузка операции присваивания = не оказывает влияние на инициализацию.

Инициализация, происходящая при передаче фактических параметров и при возврате из функции, эквивалентна инициализации вида

T x = a;

Инициализация, происходящая в выражении операции new (§R.5.3.3) и при инициализации базовых классов и членов, эквивалентна инициализации вида

T x(a);

Для массивов объектов класса с конструкторами используются при инициализации (§R.12.1) конструкторы как и для одиночных объектов. Если оказалось, что инициализаторов в списке меньше, чем элементов массива, используется стандартный конструктор (§R.12.1). Если его нет, список инициализаторов должен быть полным. Приведем пример:

complex cc = { 1, 2 }; // ошибка: необходимо

  // использовать конструктор

complex v[6] = { 1,complex(1,2),complex(),2 };

Здесь v[0] и v[3] инициализируются значением complex::complex(double), v[1] инициализируется complex::complex(double,double), а v[2], v[4] и v[5] инициализированы complex::complex().