|
Программирование >> Синтаксис инициирования исключений
public: Безаргументный конструктор - подходит Конструктор копий по умолчанию - подходит Оператор = по умолчанию - тоже подходит Set<Type>& operator+=(Type* object) { AddObject(object); return *this; } Set<Type>& operator-=(Type* object) { RemoveObject(object); return *this; } bool operator>=(Type* object) { return Exists(object); } class Iterator { private: SetBase::Iterator* iter; public: Iterator(Set&* i) : iter(s.ProvideIterator()) {} bool More() { return iter->More(); } Type* Next() { return (Type*)(iter->Next()); } Iterator* ProvideIterator() { return new Set::Iterator(*this); } Существуют и другие возможности, которые было бы неплохо добавить в параметризованный класс, но я думаю, что вы поняли общий принцип. От подобных параметризованных классов редко создаются производные, поэтому вложенный класс итератора оформлен с использованием подставляемых функция. В сущности, этот итератор можно просто объявить в стеке: Set::Iterator iter(aSet); Такой вариант работает вполне нормально, однако он не соответствует обычной идиоме возвращения итератора из коллекции. Заслуживает внимания и другой вариант: сделать SetBase переменной класса вместо закрытого базового класса. Это позволит вам упрятать SetBase в файл .cpp, чтобы клиент никогда не видел его. Для этого в шаблоне Set придется определить конструкторы и оператор =, но все остальные модификации шаблона будут простыми и незамысловатыми. Транзакции и гениальные указатели Мы подошли к последней главе, посвященной косвенным обращениям (которая, впрочем, далеко не исчерпывает этой темы). Давайте посмотрим, как развить идею умных указателей. Встречавшиеся до сих пор идиомы и примеры умных и мудрых указателей, курсоров и итераторов главным образом были локализованы в одном инкапсулированном объекте. Хватит мелочиться - пора поговорить о том, как будет выглядеть архитектура в целом, если применить эти идиомы в более широком масштабе. Указатели, рассматриваемые в этой главе, умны настолько, что становится просто страшно. Эпитеты умный и мудрый уже не описывают их в достаточной степени. Потрясающие, ослепительные, невероятно одаренные звучит слишком выспренне, поэтому я скромно назову их гениальными . Предупреждение: в этой главе проверяется не только ваше мастерство, но и воображение. Описанные ниже проблемы и идиомы напоминают узкую горную тропу, по которой можно проехать только на велосипеде. Надевайте шлем и почаще останавливайтесь, чтобы передохнуть. Тернистые пути дизайна Как правило, после описания идиом в этой книге сразу же рассматриваются их практические применения. Позвольте мне отклониться от этой традиции и обсудить некоторые проблемы дизайна, которые понадобятся нам позднее - по мере того, как будет разворачиваться действие этой главы. Транзакции В приложениях клиент/сервер и базах данных часто встречается ситуация, когда несколько удаленных пользователей обращаются с запросом на обновление одной базы или структуры данных. Квант обновления, или транзакция (transaction), с точки зрения клиента может состоять из нескольких элементарных изменений в базе или структуре данных. В таких ситуациях разработчики руководствуются несколькими правилами, позаимствованными из мира СУБД: 1. Транзакции должны быть атомарными. Либо вносятся все изменения, необходимые для совершения транзакции, либо никакие. 2. Во время обработки транзакции одного клиента данные должны выглядеть так, как они выглядели в начале незавершенных транзакций всех остальных клиентов. До момента своего завершения транзакция остается невидимой для других клиентов; все выглядит так, словно транзакция и не начиналась. 3. Если сразу несколько клиентов в своих транзакциях пытаются изменить один объект, допускается успешное завершение не более одной транзакции. Последнее правило гарантирует, что каждый объект обновляется не более чем одним клиентом. Существуют две стратегии его реализации:
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |