Язык программирования C++. Вводный курс


Инициализация массива, распределенного из хипа A


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

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

#include <utility>

#include <vector >

#include <new>

#include <cstddef>

#include "Accounts.h"

typedef pair<char*, double> value_pair;

 

/* init_heap_array()

 *     объявлена как статическая функция-член

 *     обеспечивает выделение памяти из хипа и инициализацию

 *     массива объектов

 * init_values: пары начальных значений элементов массива

 * elem_count: число элементов в массиве

 *             если 0, то размером массива считается размер вектора

 *             init_values

 */

Account*

Account::

init_heap_array(

        vector<value_pair> &init_values,

        vector<value_pair>::size_type elem_count = 0 )

{

   vector<value_pair>::size_type

          vec_size = init_value.size();

 

   if ( vec_size == 0 && elem_count == 0 )

      return 0;

 

   // размер массива равен либо elem_count,

   // либо, если elem_count == 0, размеру вектора ...

   size_t elems = elem_count

                  ? elem_count : vec_size();

 

   // получить блок памяти для размещения массива

   char *p = new char[sizeof(Account)*elems];

 

   // по отдельности инициализировать каждый элемент массива

   int offset = sizeof( Account );

   for ( int ix = 0; ix < elems; ++ix )

   {

        // смещение ix-ого элемента

        // если пара начальных значений задана,

        //      передать ее конструктору;

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

 

        if ( ix < vec_size )

           new( p+offset*ix ) Account( init_values[ix].first,

                                       init_values[ix].second );

        else new( p+offset*ix ) Account;

   }

 

   // отлично: элементы распределены и инициализированы;

   // вернуть указатель на первый элемент

   return (Account*)p;

<


Начало  Назад  Вперед



Книжный магазин