Подтвердить что ты не робот

В чем смысл класса С++ Wrapper?

У меня есть небольшая проблема в понимании класса-оболочки. Было бы здорово, если бы кто-то мог помочь предоставить примерные примеры.

  • Что такое класс С++ Wrapper и каковы обстоятельства его написания?
  • Что он использует?

Спасибо.

4b9b3361

Ответ 1

"класс-оболочка" - это де-факто термин, означающий класс, который "обертывает" ресурс; то есть управляющий ресурсом. Когда люди пишут обертку, тогда они делают что-то вроде этого:

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 предоставляет утилиту для этого, как это обычно делается для хороших идиом.

Ответ 2

Обертка - это всего лишь небольшой класс, целью которого является предоставление другого интерфейса, чем тот, который он обертывает. Например, принято использовать C API и писать один или несколько классов, которые "обертывают" его, чтобы обеспечить объектно-ориентированный интерфейс, а не процедурный.

Ответ 3

Вы спросили об обстоятельствах написания классов-оболочек. Например, если вы работаете в компании, которая использует различные типы камер, скажем USB, firewire и т.д. Каждый из производителей предоставит другой набор функций через API для запуска камеры, установки параметров и чтения потока изображений из него.

Теперь программист, который создает приложения в вашей компании, должен быть изолирован от всех конкретных деталей в различных API. Теперь, что вы можете сделать, это написать класс оболочки вокруг API для каждой из камер или умнее, только один класс с простыми функциями, обертывая существующий код, предоставляемый API.

Например, мы можем создавать классы MyUSBCameraWrapperClass, MyFirewireCameraWrapperClass с некоторыми функциями-членами, такими как setFrameRate (int fps), getImgFrame (* framebuffer) и т.д.

Затем программисты в вашей компании могут использовать MyUSBCameraWrapperClass usbcam; usbcam.setFrameRate(30) и т.д. Вы понимаете?

Ответ 4

Класс-оболочка - это класс, который обертывает функциональность другим интерфейсом.

Предположим, что у вас есть функция f():

void f() { std::cout << "hello\n"; }

Простой класс-оболочка может быть

class C {
    f() { std::cout << "hello\n"; }
};

Вы можете написать оболочку, когда ваша существующая база кода ожидает определенный интерфейс. В этом и заключается суть шаблона проектирования адаптера. Или вы можете обернуть функцию в класс, если хотите сохранить состояние для этой функции. Или вы можете обернуть функцию в конструкторе класса или деструкторе, если вы хотите, чтобы он удобно и автоматически вызывался для вас правильным и детерминированным образом. И этот список продолжается.

Ответ 5

Я использую два вида:

  • оболочки ресурсов для пар функций, предоставляемых ОС, например

    • UNIX: открыть/закрыть, mmap/munmap, dlopen/dlclose
    • Windows: CreateFile/DestroyHandle, CreateFileMapping/CloseHandle, LoadLibrary/FreeLibrary.
  • функциональные оболочки для функций, предоставляемых ОС, например

    • UNIX: запись, чтение, dlsym
    • Windows: ReadFile, WriteFile, GetProcAddress

Обертка ресурсов делает уверенным, что код, сгенерированный компилятором, беспокоится об уничтожении ресурса, созданного конструктором, через то, что сегодня называется RAII. Легко сочетать такие классы через отношения базового/членского класса в сложные классы. В случае сбоя функции создания генерируется исключение системной ошибки, предоставляющее богатую информацию об ошибке об ошибке.

Функциональная оболочка используется вместо простой функции ОС. Также в случае сбоя создается системное исключение.

Таким образом, кому-то, использующему мой код, не нужен отладчик и код отладки, чтобы выяснить, что происходит в сложной среде со многими библиотеками и процессами и удаленными машинами.

Кроме того, эти обертки предоставляют некоторую абстракцию ОС - при использовании кода их не нужно беспокоиться о различиях ОС.