5.3.5. Реализация зависимостей
Зависимости в языке C++ реализуются с помощью указателей или с помощью специальных объектов. Например, зависимость "много-к-одному" между классами Item и Group реализована через указатели: class Item{ public: virtual void cut (); virtual void move (Length deltax, Length deltay) = 0; virtual Boolean pick (Length px, Length py) = 0; virtual void ungroup () = 0; private: Group* group; friend Group::add_item (Item*); friend Group::remove_item (Item*); public: Group* get_group () {return group;}; }; class Group: public Item { public: void cut (); void move (Length deltax, Length deltay); Boolean pick (Length px, Length py) = 0; void ungroup () { }; private: ItemSet* items; public: void add_item (Item*); void remove_item (Item*); ItemSet* get_items () {return items;} };
Каждый раз, когда к зависимости добавляется (или из нее удаляется) связь, оба указателя должны быть изменены: void Group::add_item (Item* item) { item->group = this; items->add (item); } void Group::remove_item (Item* item); { item->group = 0; items->remove (item); }
Методы Group::add_item и Group::remove_item могут изменять приватные (private) атрибуты класса Item, хотя они определены в его подклассе Group, так как они определены как дружественные (friends) для класса Item.
В рассмотренном примере опущены проверки:
- не является ли включаемый в группу графический объект уже членом этой группы: в этом случае его незачем еще раз включать в группу;
- не является ли включаемый в группу графический объект членом какой-либо другой группы: в этом случае его нельзя включать в группу и необходимо выдать на экран соответствующее сообщение.
Иногда связанные между собой (зависимые) объекты включают в так называемые коллективные классы. В качестве примера такого класса рассмотрим класс ItemSet (набор объектов): class ItemSet { public: ItemSet(); //создать пустой набор объектов ~ItemSet(); //уничтожить набор объектов void add(Item*); //включить объект в набор void remove(Item*); //исключить объект из набора Boolean includes(Item*); //проверить наличие объекта в наборе int size(Item*); //определить количество объектов в наборе };
Коллективные классы часто используются в библиотеках классов. При работе с коллективными классами удобно использовать итераторы, т.е. объекты, с помощью которых можно "просмотреть" коллектив.
Зависимости между классами можно реализовать и с помощью специальных классов (каждый объект такого класса описывает связь между объектами соответствующих классов). В этом случае атрибуты класса соответствуют атрибутам описываемой им зависимости.