Во время изучения Qt я столкнулся с этой проблемой с набором взаимосвязанных виджетов, которые я хотел обновить «атомарно». Мне понравилось решение @ cjhuitt, но я обнаружил, что оно идет еще лучше с небольшим количеством синтаксического сахара на основе прокси-объектов . Вот подход, который я использовал ...
Сначала я определил шаблон класса для прокси-объекта-блокировщика. Как и у Калеба, это блокирует сигналы при строительстве, а затем восстанавливает их прежнее состояние при разрушении. Однако он также перегружает оператор ->
для возврата указателя на заблокированный объект:
template<class T> class Blocker {
T *blocked;
bool previous;
public:
Blocker(T *blocked)
: blocked(blocked),
previous(blocked->blockSignals(true)) {}
~Blocker() { blocked->blockSignals(previous); }
T *operator->() { return blocked; }
};
Затем я определил небольшую шаблонную функцию для создания и возврата блокировщика:
template<class T> inline Blocker<T> whileBlocking(T *blocked) {
return Blocker<T>(blocked);
}
Сложив все это вместе, я бы использовал это так:
whileBlocking(checkBox)->setChecked(true);
или
whileBlocking(xyzzySpin)->setValue(50);
Это дает мне все преимущества RAII с автоматически спаренной блокировкой и восстановлением вокруг вызова метода, но мне не нужно называть какую-либо оболочку или флаги состояния. Это красиво, просто и чертовски надежно.