// вектор на десять элементов со значениями от 0 до 9

vector *pv = new vector{0,1,2,3,4,5,6,7,8,9};

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

string *ps1 = new string;  // инициализация по умолчанию пустой строкой

string *ps = new string(); // инициализация значением по умолчанию

                           // (пустой строкой)

int *pi1 = new int;        // инициализация по умолчанию;

                           // значение *pi1 не определено

int *pi2 = new int();      // инициализация значением по умолчанию 0;

                           // *pi2 = 0

Для типов классов (таких как string), определяющих собственные конструкторы (см. раздел 7.1.4), запрос инициализации значением по умолчанию не имеет последствий; независимо от формы, объект инициализируется стандартным конструктором. Различие существенно в случае встроенных типов: инициализация объекта встроенного типа значением по умолчанию присваивает ему вполне конкретное значение, а инициализация по умолчанию — нет. Точно так же полагающиеся на синтезируемый стандартный конструктор члены класса встроенного типа также не будут не инициализированы, если эти члены не будут инициализированы в теле класса (см. раздел 7.1.4).

По тем же причинам, по которым обычно инициализируют переменные, имеет смысл инициализировать и динамически созданные объекты.

Когда предоставляется инициализатор в круглых скобках, для вывода типа объекта, который предстоит зарезервировать для этого инициализатора, можно использовать ключевое слово auto (см. раздел 2.5.2). Но, поскольку компилятор использует тип инициализатора для вывода резервируемого типа, ключевое слово auto можно использовать только с одиночным инициализатором в круглых скобках:

auto p1 = new auto(obj); // p указывает на объект типа obj

                         // этот объект инициализируется значением obj

auto p2 = new auto{a,b,c}; // ошибка: для инициализатора нужно

                           // использовать круглые скобки

Тип p1 — это указатель на автоматически выведенный тип obj. Если obj имеет тип int, то тип p1 — int*; если obj имеет тип string, то тип p1string* и т.д. Вновь созданный объект инициализируется значением объекта obj.

Динамически созданные константные объекты

Для резервирования константных объектов вполне допустимо использовать оператор new:

// зарезервировать и инициализировать

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

// зарезервировать и инициализировать значением по умолчанию

const string const string *pcs = new const string;

Подобно любым другим константным объектам, динамически созданный константный объект следует инициализировать. Динамический константный объект типа класса, определяющего стандартный конструктор (см. раздел 7.1.4), можно инициализировать неявно. Объекты других типов следует инициализировать явно. Поскольку динамически зарезервированный объект является константой, возвращенный оператором new указатель является указателем на константу (см. раздел 2.4.2).

Исчерпание памяти

Хотя современные машины имеют огромный объем памяти, всегда существует вероятность исчерпания динамической памяти. Как только программа использует всю доступную ей память, выражения с оператором new будут терпеть неудачу. По умолчанию, если оператор new неспособен зарезервировать требуемый объем памяти, он передает исключение типа bad_alloc (см. раздел 5.6). Используя иную форму оператора new, можно воспрепятствовать передаче исключения:

// при неудаче оператор new возвращает нулевой указатель

int *p1 = new int; // при неудаче оператор new передает

                   // исключение std::bad_alloc

int *p2 = new (nothrow) int; // при неудаче оператор new возвращает

                             // нулевой указатель

Перейти на страницу:

Похожие книги