Читать «Справочное руководство по 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().