Программирование >>  Инициализация объектов класса, структура 

1 ... 129 130 131 [ 132 ] 133 134 135 ... 395


8.4.5. Оператор размещения new А

Существует третья форма оператора new, которая создает объект без отведения для него памяти, то есть в памяти, которая уже была выделена. Эту форму называют оператором размещения new. Программист указывает адрес области памяти, в которой размещается объект:

new (place address) type-specifier

place address должен быть указателем. Такая форма (она включается заголовочным файлом <new>) позволяет программисту предварительно выделить большую область памяти, которая впоследствии будет содержать различные объекты. Например:

8.4.4. Динамическое создание и уничтожение константных объектов

Программист способен создать объект в хипе и запретить изменение его значения после инициализации. Этого можно достичь, объявляя объект константным. Для этого применяется следующая форма оператора new:

const int *pci = new const int(1024);

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

Во-вторых, указатель, возвращаемый выражением new, должен адресовать константу. В предыдущем примере pci служит указателем на const int.

Константность динамически созданного объекта подразумевает, что значение, полученное при инициализации, в дальнейшем не может быть изменено. Но поскольку объект динамический, временем его жизни управляет оператор delete. Например:

delete pci;

Хотя операнд оператора delete имеет тин указателя на const int, эта инструкция является корректной и освобождает область памяти, на которую ссылается pci.

Невозможно создать динамический массив константных элементов встроенного типа потому, что, как мы отмечали выше, элементы такого массива нельзя проинициализировать в операторе new. Следующая инструкция приводит к ошибке компиляции:

const int *pci = new const int[100]; ошибка



#include <iostream> #include <new> const int chunk = 16; class Foo {

public:

int val() { return val; } FooQ() { val = 0; } private:

int val;

выделяем память, но не создаем объектов Foo char *buf = new char[ sizeof(Foo) * chunk ];

int main() {

создаем объект Foo в buf Foo *pb = new (buf) Foo;

проверим, что объект помещен в buf if ( pb.val() == 0 )

cout << Оператор new сработал! << endl;

здесь нельзя использовать pb

delete[] buf;

return 0;

Результат работы программы:

i Оператор new сработал!

Для оператора размещения new нет парного оператора delete: он не нужен, поскольку эта форма не выделяет память. В предыдущем примере необходимо освободить память, адресуемую указателем buf, а не pb. Это происходит в конце программы, когда буфер больше не нужен. Поскольку buf ссылается на символьный массив, оператор delete имеет форму

delete[] buf;

При уничтожении buf прекращают существование все объекты, созданные в нем. В нашем примере pb больше не ссылается на существующий объект класса Foo.

Упражнение 8.5

(a) const float *pf = new const float[100];

(b) double *pd = new doub1e[10] [getDim()];

(c) int (*pia2)[ 1024 ] = new int[ ][ 1024 ];

Объясните, почему приведенные операторы new ошибочны:

(d) const int *pci = new const int;

Упражнение 8.6

Как бы вы уничтожили pa?



int globalObj; char buf[1000];

void f() {

int *pi = &global0bj;

double *pd = 0;

float *pf = new float(O); int *pa = new(buf)int[20];

delete pi; (a) delete pd; (b)

delete pf; (c) de1ete[] pa; (d)

выполнения и почему:

Упражнение 8.8

Какие из данных объявлений auto ptr неверны или грозят ошибками времени

int ix = 1024;

int *pi = & ix; int *pi2 = new int ( 2048 );

(a) auto ptr<int> p0(ix);

(b) auto ptr<int> pl(pi);

(c) auto ptr<int> p2(pi2);

(d) auto ptr<int> p3(&ix);

(e) auto ptr<int> p4(new int(2048));

(f) auto ptr<int> p5(p2.get()) ; (9) auto ptr<int> p6(p2.release());

выполнения? Объясните каждый случай.

(h) auto ptr<int> p7(p2);

Упражнение 8.9

int *pi0 = p2.get();

Объясните разницу между следующими инструкциями:

int *pi1 = p2.release() ;

Для каких случаев более приемлем тот или иной вызов? Упражнение 8.10

typedef int arr[10];

int *pa = new arr; Упражнение 8.7

Какие из следующих операторов delete содержат потенциальные ошибки времени



1 ... 129 130 131 [ 132 ] 133 134 135 ... 395

© 2006 - 2024 pmbk.ru. Генерация страницы: 0.004
При копировании материалов приветствуются ссылки.
Яндекс.Метрика