Идиомы и стили С++ | страница 41
>
>class CTransaction {
> friend class CLockable;
>private:
> // коллекция зарегистрированных объектов
> ampstack‹CLockable› m_locks;
> // добавить объект к транзакции
> void addLock (CLockable*);
>public:
> virtual ~CTransaction ();
>// закрепить или отменить все изменения во всех
>// зарегистрированных объектах.
> void commit();
> void rollback();
>// проверить, зарегистрирован ли объект в этой транзакции
> int allready_locked(CLockable*);
>};
>// зарегистрироваться в транзакции
>inline int CLockable::regObj (CTransaction* _pt) {
> if (m_trans!= NULL) return 0;
> else {
> _pt-›addLock(this);
> m_trans = _pt;
> return 1;
> }
>}
>// разрегистрироваться
>inline void CLockable::unregObj() {
> m_trans = NULL;
>}
>// добавление объекта к транзакции.
>inline void CTransaction::addLock(CLockable* _lc) {
> // а именно, воткнуть указатель на него в стек.
> m_locks.push (_lc);
>}
>// закрепление всех объектов
>void CTransaction::commit() {
> // создаем итератор
> ampIter‹CLockable› it(&(this-›m_locks));
> // пробежались по всем, закрепились.
> it.goStart();
> while (!it.isLast()) it.moveNext()-›commit();
> // Всех выкинуть из стека, разрегистрировать.
> while (!m_locks.isEmpty()) m_locks.pop()-›unregObj();
>}
>// отмена всех объектов
>void CTransaction::rollback() {
> // создали итератор
> ampIter‹CLockable› it(&(this-›m_locks));
> // пробежались по всем, отменились.
> it.goStart();
> while (!it.isLast()) it.moveNext()-›rollback();
> // Всех выкинуть из коллекции и разрегистрировать
> while (!m_locks.isEmpty()) m_locks.pop()-›unregObj();
>}
>// проверка, зарегистрирован ли объект.
>int CTransaction::allready_locked(CLockable* _lc) {
> // создали итератор
> ampIter‹CLockable› it(&(this-›m_locks));
> it.goStart();
> while (!it.isLast()) if (it.moveNext() == _lc) return 1;
> return 0;
>}
Шаг 29 - Единственный экземпляр класса - Одиночка или Singleton.
Как гарантировать единичность экземпляра некоего класса?
Предположим, что Вы проектируете программную систему, в которой некое устройство должно быть исключительно в одном экземпляре. Какие у нас варианты?
1. Создать класс устройства, объявить его экземпляр в специальном файле globals.cpp, и обязать программистов использовать строго его (именно так я делал на заре карьеры; наш шеф под роспись давал нам "Меморандум о писании программ", там много было интересного).
2. Создать класс устройства, объявить в нем устройство статическим членом.
3. Реализовать в классе устройства подсчет экземпляров, ограничить максимальное количество единицей.
4. Создать "закрытый" класс устройства, создать смарт-указатель на него так, чтобы смарт следил за одиночеством класса устройства.