Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 [ 65 ] 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105

Окончание табл. 7.1

Выражение

Семантика

storageimpl.operator->()

storageimpl.operator*()

Storagelmpl<T>::StoredType p; p = storageimpl.Defaul t(); storageimpl.Destroy()

Возвращает объект типа

Storageimpl<Т>:: -.PointerType. Используется оператором -> класса SmartPtr

Возвращает объект типа Storageimpl<т>::ReferenceType. Используется оператором * класса SmartPtr

Возвращает значение, заданное по умолчанию (обычно нуль)

Разрущает объект, на который ссылается интеллектуальный указатель

7.14.2. Стратегия Ownership

Стратегия Ownership должна поддерживать как внедренный, так и независимый подсчет ссылок. Следовательно, она должна использовать явные вызовы функции, а не механизм конструкторов и деструкторов, как это сделано в работе (Koenig, 1996). Дело в том, что функцию-член можно вызвать в любое время, а конструкторы и деструкторы вызываются автоматически и только в определенные моменты времени.

Реализация стратегии Ownership имеет один шаблонный параметр, соответствующий ссылочному типу. Класс SmartPtr передает параметр storagePolicy<T>::PointerType классу OwnershipPolicy. Обратите внимание на то, что шаблонный параметр класса OwnershipPolicy является типом указателя, а не объекта, на который он ссылается.

Если класс Ownershiplmpl является реализацией стратегии ownership, а owner-shiplmpl - это объект типа Ownershi plmpl <Р>, то применяются конструкции, указанные в табл. 7.2.

Таблица 7.2. Конструкции стратегии Ownership

Выражение

Семантика

Р vail;

Р val2 = Ownershiplmpl.Clone(vall);

const P vail;

P val2 = ownershiplmpl.

Clone(vall);

P val;

bool unique = ownershiplmpl. Release(val);

bool dc = Ownershiplmpl<P>:: destructiveCopy;

Клонирует объект. Может модифицировать исходное значение, если в стратегии Ownership применяется разрушающее копирование

Клонирует объект

Освобождает объект. Возвращает значение true, если была освобождена последняя ссылка на объект

Устанавливает, должна ли стратегия Ownership применять разрушающее копирование. Если да, класс SmartPtr применяет примем Колвина-Гиббонса (Meyers, 1999), использованный в классе Std: .auto ptr



Реализация стратегии Ownership, основанной на подсчете ссылок, выглядит следующим образом.

template <class Р> class RefCounted {

unsigned int* pCount ; protected:

RefCountedC) : pCount Cnew unsigned intCl)) {}

P CloneCconst P & val)

++*pCount ; return val;

bool ReleaseCconst P&) {

if (!-*pCount ) {

delete pCount ; return true;

return false;

enum { destructiveCopy = false } ; см. ниже

Реализовать эту стратегию на основе других схем подсчета ссылок так же просто. Рассмотрим реализацию стратегии Ownership для СОМ-объектов. Эти объекты имеют две функции: Add ref и Release. При последнем вызове функции Release объект раз-рущается. Нужно лищь передать адрес функции clone в качестве параметра функции AddRef и адрес функции Release в качестве параметра функции Release, принадлежащей СОМ-объекту.

template <class Р> class COMRefCounted {

public:

static P CloneCconst P& val) {

val->AddRefC); return val;

static bool ReleaseCconst P& val) {

val->ReleaseC); return false;

enum { destructiveCopy = false }; см. ниже

В библиотеке Loki определены следующие реализации стратегии Ownership.

• Класс DeepCopy, описанный в разделе 7.5. L В нем предполагается, что в классе, на объекты которого ссылается указатель (pontee class), реализована функция-член Clone.

• Класс RefCounted, описанный в разделе 7.5.3 и в данном разделе.

• Класс RefCountedMT, многопоточная версия класса RefCounted.

• Класс ComRefCounted - вариант внедренного подсчета ссылок, описанный в данном разделе.



• Класс Ref Linked, описанный в разделе 7.5.4.

• Класс DestructiveCopy, описанный в разделе 7.5.5.

• Класс NoCopy, который не определяет функцию Clone, блокируя любой вид копирования.

7.14.3. Стратегия Conversion

Это довольно простая стратегия: она определяет булевскую статическую константу, значение которой зависит от того, разрешено в классе SmartPtr неявное преобразование в базовый тип указателя или нет.

Если класс Conversionimpl является реализацией стратегии Conversion, применяются конструкции, приведенные в табл. 7.3.

Базовый тип указателя класса SmartPtr определяется стратегией storage и классом Storageimpl<т>::PointerType.

Как и следовало ожидать, в библиотеке Loki точно определены две реализации стратегии Convesrion.

• Класс AllowConversion.

• Класс DisallowConversion.

Таблица 7.3. Конструкции стратегии Conversion

Выражение Семантика

bool allowConv = Если константа allow имеет значение true, класс

Conversionlmpl<P>: :allow; SmartPtr допускает неявное преобразование в

базовый тип указателя

7.14.4. Стратегия Checldng

Как указывалось в разделе 7.10, проверять объекты класса SmartPtr можно во время инициализации и перед разыменованием. Во время проверки можно использовать макрос assert, исключительные ситуации, ленивую инициализацию или вообще ничего не делать.

Стратегия Checking оперирует классом storedType, принадлежащим сфатегии storage, а не типом Poi nterType. (Определение стратегии storage дано в разделе 7.14.1.)

Если S - это сохраняемый тип, определенный в реализации стратегии Storage, класс Checkimpl реализует стратегии Checking, а checkinglmpl - это объект типа Checki nglmpl<S>, то применяются конструкции, указанные в табл. 7.4.

Таблица 7.4. Конструкции стратегии Checking

Выражение Семантика

S value; Объект класса SmartPtr вызывает функцию Оп-

checkinglmpl .OnDefault(value) ; Default при вызове конструктора по умолчанию.

Если в классе Checki nglmpl эта функция не определена, конструктор по умолчанию блокируется на этапе компиляции

S value; Объект класса SmartPtr вызывает функцию Оп-

checkingimpl .Oninit(value) ; mit при вызове конструктора



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 [ 65 ] 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105