У меня есть небольшая проблема в понимании класса-оболочки. Было бы здорово, если бы кто-то мог помочь предоставить примерные примеры.
- Что такое класс С++ Wrapper и каковы обстоятельства его написания?
- Что он использует?
Спасибо.
У меня есть небольшая проблема в понимании класса-оболочки. Было бы здорово, если бы кто-то мог помочь предоставить примерные примеры.
Спасибо.
"класс-оболочка" - это де-факто термин, означающий класс, который "обертывает" ресурс; то есть управляющий ресурсом. Когда люди пишут обертку, тогда они делают что-то вроде этого:
class int_ptr_wrapper
{
public:
int_ptr_wrapper(int value = 0) :
mInt(new int(value))
{}
// note! needs copy-constructor and copy-assignment operator!
~int_ptr_wrapper()
{
delete mInt;
}
private:
int* mInt;
};
Этот класс управляет ( "wraps" ) указателем на int
. Все ресурсы должны быть обернуты каким-то образом, для чистоты (без явного очищения кода или шума) и правильности (деструктор гарантированно работает, не может забыть очистить и безопасно с исключениями).
Этот шаблон называется облачным управлением ресурсами (SBRM), хотя гораздо более распространенное (но наиболее эзотерическое) имя - это инициализация ресурсов (RAII). Идея состоит в том, чтобы связать очистку ресурса с деструктором по причинам, указанным выше: область действия обрабатывает остальные.
Обратите внимание, что я сказал, что отсутствует экземпляр-конструктор и оператор присваивания копии. Это связано с Правилом трех. (См. Связанный вопрос для подробного объяснения.) Самый простой способ правильно реализовать это правило - с помощью идиомы copy-and-swap, объясненной здесь.
Иногда, это не прагматично писать класс-оболочку для очистки ресурсов, обычно, когда ресурс уникален или используется один раз. (Или с транзакционным программированием.) Решение этого называется защитой области, способ записи кода очистки внутри функции, которая ему нужна.
Вы можете найти дополнительную информацию, выполнив поиск в своем любимом поисковом устройстве (то есть Google) или перейдя в "основной" документ здесь. Обратите внимание, что Boost предоставляет утилиту для этого, как это обычно делается для хороших идиом.
Обертка - это всего лишь небольшой класс, целью которого является предоставление другого интерфейса, чем тот, который он обертывает. Например, принято использовать C API и писать один или несколько классов, которые "обертывают" его, чтобы обеспечить объектно-ориентированный интерфейс, а не процедурный.
Вы спросили об обстоятельствах написания классов-оболочек. Например, если вы работаете в компании, которая использует различные типы камер, скажем USB, firewire и т.д. Каждый из производителей предоставит другой набор функций через API для запуска камеры, установки параметров и чтения потока изображений из него.
Теперь программист, который создает приложения в вашей компании, должен быть изолирован от всех конкретных деталей в различных API. Теперь, что вы можете сделать, это написать класс оболочки вокруг API для каждой из камер или умнее, только один класс с простыми функциями, обертывая существующий код, предоставляемый API.
Например, мы можем создавать классы MyUSBCameraWrapperClass, MyFirewireCameraWrapperClass с некоторыми функциями-членами, такими как setFrameRate (int fps), getImgFrame (* framebuffer) и т.д.
Затем программисты в вашей компании могут использовать MyUSBCameraWrapperClass usbcam; usbcam.setFrameRate(30) и т.д. Вы понимаете?
Класс-оболочка - это класс, который обертывает функциональность другим интерфейсом.
Предположим, что у вас есть функция f()
:
void f() { std::cout << "hello\n"; }
Простой класс-оболочка может быть
class C {
f() { std::cout << "hello\n"; }
};
Вы можете написать оболочку, когда ваша существующая база кода ожидает определенный интерфейс. В этом и заключается суть шаблона проектирования адаптера. Или вы можете обернуть функцию в класс, если хотите сохранить состояние для этой функции. Или вы можете обернуть функцию в конструкторе класса или деструкторе, если вы хотите, чтобы он удобно и автоматически вызывался для вас правильным и детерминированным образом. И этот список продолжается.
Я использую два вида:
оболочки ресурсов для пар функций, предоставляемых ОС, например
функциональные оболочки для функций, предоставляемых ОС, например
Обертка ресурсов делает уверенным, что код, сгенерированный компилятором, беспокоится об уничтожении ресурса, созданного конструктором, через то, что сегодня называется RAII. Легко сочетать такие классы через отношения базового/членского класса в сложные классы. В случае сбоя функции создания генерируется исключение системной ошибки, предоставляющее богатую информацию об ошибке об ошибке.
Функциональная оболочка используется вместо простой функции ОС. Также в случае сбоя создается системное исключение.
Таким образом, кому-то, использующему мой код, не нужен отладчик и код отладки, чтобы выяснить, что происходит в сложной среде со многими библиотеками и процессами и удаленными машинами.
Кроме того, эти обертки предоставляют некоторую абстракцию ОС - при использовании кода их не нужно беспокоиться о различиях ОС.