Программирование >>  Перегруженные имена функций и идентификаторы 

1 ... 121 122 123 [ 124 ] 125 126 127 ... 210


private: A* pa; public:

PA(A* p){pa = p; p->addref();}

~PA(){pa->release();}

A* operator ->(){return pa;}

Что мы видим? Есть класс PA, который умеет принимать нормальный указатель на объект класса A и выдавать его же по обращению к селектору членов класса. Ну и что? - скажете вы, - Как это может помочь? . За помощью обратимся к двум примерам, которые иллюстрирует эффективность использования класса PA:

A* pa = new A(); pa->addref(); pa->do something(); pa->release();

PA pa = new A(); pa->do something();

Посмотрим внимательнее на эти два отрывка... Что видим? Видим экономию двух строчек кода. Здесь вы наверное скажете: И что, ради этого мы столько старались? . Но это не так, потому что с введением класса PA мы переложили на него все неприятности со своевременными вызовами addref и release для класса A. Вот это уже что-то стоит!

Дальше больше, можно добавить всякие нужные штучки, типа оператора присваивания, еще одного селектора (или как его некоторые называют разименователь указателя) и так далее. Таким образом получится удобная вещь (конечно, если все это дело завернуть в шаблон.

Теперь немного сменим направление рассуждений. Оказывается существуют такие вещи, как Мудрые указатели ,



Ведущие указатели , Гениальные указатели , Грани , Кристаллы - в общем, хватает всякого добра. Правда, в практичности этих поделок можно усомниться, несмотря на их изящество . То есть, конечно, они полезны, но не являются, своего рода, панацеей (кроме ведущих указателей).

В общем особую роль играют только ведущие и умные указатели.

Начнем с такого класса как Countable, который будет отвечать за подсчет чего либо.

Итак он выглядит примерно так (в дальнейшем будем опускать реализации многих функций из-за их тривиальности, оставляя, тем самым, только их объявления:

class Countable

private:

int count; public:

int increment ();

int decrement ();

Здесь особо нечего говорить, кроме того, что, как всегда, этот класс можно сделать более удобным , добавив такие вещи, как поддержку режима многопоточности и т.д.

Следующий простой класс прямо вытекает из многопоточности и осуществляет поддержку этого режима для своих детей:

class Lockable

public:

void lock(); void unlock(); bool islocked();

Этот класс не вносит никакой новизны, но стандартизует поддержку многопоточности при использовании, например, различных платформ.



Теперь займемся собственно указателями:

class AutoDestroyable : public Countable

public:

virtual int addref ();

virtual int release (); protected:

virtual ~AutoDestroyable();

Из кода видно, что этот класс занимается подсчетом ссылок и убивает себя если пришло время .

А сейчас процитируем код умного указателя, для того чтобы синхронизовать наши с вами понимание этого чуда.

template <class T> class SP

private:

T* m pObject; public:

SP ( T* pObject){ m pObject = pObject; }

~SP () { if( m pObject ) m pObject->release (); }

T* operator -> ();

T& operator * ();

operator T* ();

Это уже шаблон, он зависит от объекта класса, к которому применяется. Задача умного указателя была рассмотрена выше и итог при сравнении с ситуацией без его использования положителен только тем, что для объекта, создаваемого в куче, не надо вызывать оператор delete - он сам вызовется, когда это понадобится.

Теперь остановимся на минутку и подумаем, когда мы можем использовать этот тип указателей, а когда нет. Главное требование со стороны SP, это умение основного объекта вести подсчет ссылок на себя и уничтожать себя в тот момент, когда он не становится нужен. Это серьезное ограничение, поскольку не во все используемые классы вы сможете добавить эти



1 ... 121 122 123 [ 124 ] 125 126 127 ... 210

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика