В OpenGL часто пишут такой код:
glPushMatrix();
// modify the current matrix and use it
glPopMatrix();
По существу, состояние изменяется, затем выполняются некоторые действия, использующие новое состояние, и, наконец, состояние восстанавливается.
Теперь есть две проблемы:
- Легко забыть восстановить состояние.
- Если промежуточный код выдает исключение, состояние никогда не восстанавливается.
В истинном объектно-ориентированном стиле программирования я написал несколько служебных классов для решения этих проблем, например:
struct WithPushedMatrix {
WithPushedMatrix() { glPushMatrix(); }
~WithPushedMatrix() { glPopMatrix(); }
};
Теперь я могу просто написать свой предыдущий пример следующим образом:
WithPushedMatrix p;
// modify the current matrix and use it
Точный момент восстановления определяется временем жизни p
.Если выдается исключение, вызывается деструктор p
, восстанавливается состояние, и жизнь хороша.
Тем не менее, я не совсем счастлив.Особенно, если конструктор принимает некоторые аргументы (например, флаги для glEnable
), легко забыть присвоить объект переменной:
WithEnabledFlags(GL_BLEND); // whoops!
Временное уничтожается немедленно, а изменение состояния преждевременно отменяется..
Другая проблема заключается в том, что любой, кто читает мой код, может запутаться: «Почему объявленная здесь переменная никогда не используется? Давайте избавимся от нее!»
Итак, мои вопросы: Это хороший шаблон?Может быть, у него есть имя?Есть ли проблемы с этим подходом, который я пропускаю?И последнее, но не менее важное: есть ли хорошие альтернативы?
Обновление : Да, я думаю, это форма RAII.Но не так, как обычно используется RAII, потому что он включает в себя, казалось бы, бесполезную переменную;рассматриваемый «ресурс» никогда не доступен явно.Я просто не осознавал, что это конкретное использование было настолько распространенным.