Язык программирования C++


"Интеллигентный указатель" - часть 2


template <class T> SmartPtr<T>::SmartPtr(T* ptr) { if (ptr == 0) refPtr = 0; else { refPtr = new Ref<T>; refPtr->realPtr = ptr; refPtr->counter = 1; } }

Деструктор уменьшает количество ссылок на 1 и, если оно достигло 0, уничтожает объект

template <class T> SmartPtr <T>::~SmartPtr() { if (refPtr != 0) { refPtr->counter--; if (refPtr->counter <= 0) { delete refPtr->realPtr; delete refPtr; } } }

Реализация операций -> и * довольно проста:

template <class T> T* SmartPtr<T>::operator->() const { if (refPtr != 0) return refPtr->realPtr; else return 0; } template <class T> T& SmartPtr<T>::operator*() const { if (refPtr != 0) return *refPtr->realPtr; else throw bad_pointer; }

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

template <class T> SmartPtr<T>::SmartPtr(const SmartPtr& s):refPtr(s.refPtr) { if (refPtr != 0) refPtr->counter++; }

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

template <class T> SmartPtr& SmartPtr<T>::operator=(const SmartPtr& s) { // отсоединиться от имеющегося указателя if (refPtr != 0) { refPtr->counter--; if (refPtr->counter <= 0) { delete refPtr->realPtr; delete refPtr; } } // присоединиться к новому указателю refPtr = s.refPtr; if (refPtr != 0) refPtr->counter++; }

В следующей функции при ее завершении объект класса Complex будет уничтожен:

void foo(void) { SmartPtr<Complex> complex(new Complex); SmartPtr<Complex> ptr = complex; return; }




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



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