|
Программирование >> Формирование пользовательского контейнера
[002F1300] О 3 [002F12D0] О 2 [002F12A0] О 1 Deleting: 3 Deleting: 2 Deleting: 1 After garbage collection for gclist<int, 0>: memPtr refcount value [002F1310] 1 4 *p: 4 GCPtr going out of scope. Before garbage collection for gclist<int, 0>: memPtr refcount value t002F1310] 0 4 Deleting: 4 After garbage collection for gclist<int, 0>: memPtr refcount value - Enpty ~ В программе объекту p типа GCPtr<int> по очереди присваивается указатель на 4 отдельных участка динамической памяти, инициализированных с разными значениями. Далее вызывается функция collect (), которая запускает сбор мусора. Обратите внимание на содержимое списка gclist: три его элемента помечены как неактивные, и только элемент, указывающий на память, выделенную последней, до сих пор используется. Далее неактивные элементы списка удаляются. В конце концов, программа заверщается, объект р выходит за пределы области видимости и последний элемент списка уничтожается. Обратите внимание на то, что у первых трех фрагментов динамической памяти, на которые указывает объект р, нулевые счетчики ссылок. Это результат работы перегруженной операции присваивания. Когда объекту GCPtr присваивается новый адрес, счетчик ссылок для его текущего значения уменьшается. Еще одно замечание: так как объект р инициализируется при объявлении, в списке gclist не формируется ни одного элемента с пустым адресом. Напоминаю, что подобный элемент создается, только если объект GCPtr объявляется без начального значения. размещение массивов Если вы декларируете массив с помощью операции new, вы должны сообщить об этом объекту GCPtr, указав размер массива при объявлении этого обьекта. Далее приведен пример, в котором выделяется память для массива из 5 элементов типа double. GCPtr<double. 5> pda = new double[5]; Размер следует задать по двум причинам. Во-первых, вы известите конструктор объекта типа ccptr о том, что создаваемый объект будет указывать на размещенный массив, что вызовет установку значения true в поле isArray. Если это поле равно true, функция collect () будет очищать память с помощью операции deiete[], которая предназначена для удаления размещенного в динамической памяти массива, в отличие от операции delete, используемой для уничтожения одиночного объекта. Следовательно, в приведенном примере, когда pda выхолит за пределы видимости, применяется операция delete [] и все пять элементов массива будут удалены. Уверенность в том, что нужное количество элементов уничтожается, особенно важна, когда массивы из объектов размещаются в динамической памяти. Только используя операцию delete [ ], вы можете быть уверены, что для каждого объекта из массива будет вызван деструктор. Во-вторых, указание размера массива препятствует обращению к элементу, находящемуся за границами массива, во время обработки его элементов в цикле с помощью объекта iter. Напоминаю, что размер массива (хранящийся в поле arraySize) передается через объект ccPtr конструктору объекта типа Iter, как только последний потребуется. Знайте, что в языке нет строгого правила, по которому динамически размещаемый массив может обрабатываться только с помощью объекта cscptr, указывающего на массив. Его соблюдение - целиком на вашей ответственности. После того как вы разместили массив в динамической памяти, есть два способа доступа к его элементам. Во-первых, вы можете индексировать объект типа GCPtr, который на него указывает. Во-вторых, можно воспользоваться итератором. Далее показаны оба способа доступа. Применение индексирования Приведенная в листинге 2.5 программа создает объект GCPtr, указывающий иа массив, состоящий из 10 элементов типа int. Далее она распределяет в динамической памяти такой массив и инициализирует его значениями Jbix чисел от О до 9. В завершение, эти значения выводятся на экран. Программа выполняет перечисленные действия с помощью индексирования объекта GCPtr. #include <iostreain> #include <new> #include gc.h using namespace std; int mainO { Создает объект GCPtr для указания на массив из 10 элементов типа int. GCPtr<int, 10> ар = new int[10]; Присваивает массиву значения с помощью индексирования, for(int i=0; i < 10; i++) ap[ij = i; Теперь выводит содержимое массива, for(int i=0; i < 10; i++) cout ap[i] ; cout endl; } catch(bad alloc exc) { cout Allocation failure!\n ; return 1; return 0; Вывод программы при выключенном режиме отображения приведен далее. 012345 6 789 Поскольку объект GCPtr - обычный указатель языка С++, никакой проверки границ не проводится, поэтому возможен доступ к элементам за границами размешенного в динамической памяти массива. Следовательно, обращайтесь к массиву с помощью объекта типа GCPtr с той же тщательностью, с какой вы обрабатываете массив с помошью обычного указателя языка С++. Листинг 2.5. Демонстрация индексирования объекта ecptr
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |