Язык программирования C++ для профессионалов



         

Управляющие классы - часть 2


class set_handle { set* rep; public: set* operator->() { return rep; }

set_handler(set* pp) : rep(pp) { } };

Это не слишком влияет на работу с множествами, просто передаются объекты типа set_handle вместо объектов типа set& или set*, например:

void my(set_handle s) { for (T* p = s->first(); p; p = s->next()) { // ... } // ... }

void your(set_handle s) { for (T* p = s->first(); p; p = s->next()) { // ... } // ... }

void user() { set_handle sl(new slist_set); set_handle v(new vector_set v(100));

my(sl); your(v);

my(v); your(sl); }

Если классы set и set_handle разрабатывались совместно,легко реализовать подсчет числа создаваемых множеств:

class set { friend class set_handle; protected: int handle_count; public: virtual void insert(T*) = 0; virtual void remove(T*) = 0;

virtual int is_member(T*) = 0;

virtual T* first() = 0; virtual T* next() = 0;

set() : handle_count(0) { } };

Чтобы подсчитать число объектов данного типа set, в управляющем классе нужно увеличивать или уменьшать значение счетчика set_handle:

class set_handle { set* rep; public: set* operator->() { return rep; }

set_handle(set* pp) : rep(pp) { pp->handle_count++; } set_handle(const set_handle& r) : rep(r.rep) { rep->handle_count++; }

set_handle& operator=(const set_handle& r) { rep->handle_count++; if (--rep->handle_count == 0) delete rep; rep = r.rep; return *this; }

~set_handle() { if (--rep->handle_count == 0) delete rep; } };

Если все обращения к классу set обязательно идут через set_handle, пользователь может не беспокоиться о распределении памяти под объекты типа set.

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




Содержание  Назад  Вперед