Что означает класс C ++ Wrapper? - PullRequest
38 голосов
/ 15 марта 2011

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

  1. Что такое класс C ++ Wrapper и каковы обстоятельства его написания?
  2. Для чего он нужен?

Спасибо.

Ответы [ 5 ]

31 голосов
/ 15 марта 2011

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

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;
};

Этот класс управляет ("оборачивает") указателем на int.Все ресурсы должны быть обернуты каким-либо образом для обеспечения чистоты (без явного кода очистки или шума) и правильности (деструктор гарантированно работает; не может забыть очистить и безопасен за исключением).

Этот шаблонназывается управлением ресурсами с привязкой к объему (SBRM), хотя гораздо более распространенным (но наиболее эзотерическим) именем является «Приобретение ресурсов» - «Инициализация» (RAII).Идея состоит в том, чтобы связать очистку ресурса с деструктором по причинам, указанным выше: область действия обрабатывает все остальное.

Обратите внимание, что я сказал, что в нем отсутствуют конструктор копирования и оператор назначения копирования.Это связано с правилом трех .(См. Связанный вопрос для подробного объяснения.) Самый простой способ правильно реализовать это правило - использовать идиому копирования и замены, объясненное здесь .


Иногда это не прагматичнонаписать класс-оболочку для очистки ресурса, обычно, когда ресурс уникален или используется один раз.(Или с транзакционным программированием.) Решение этой проблемы называется scope guard , способ написания кода очистки внутри функции, которая в этом нуждается.

Дополнительную информацию можно найти, выполнив поискдля этого в вашем любимом поисковом провайдере (то есть в Google) или переходите к «основному» документу здесь .Обратите внимание, что Boost предоставляет утилиту для этого, как это обычно делается для хороших идиом.

10 голосов
/ 15 марта 2011

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

7 голосов
/ 10 августа 2011

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

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

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

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

3 голосов
/ 15 марта 2011

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

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

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

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

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

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

2 голосов
/ 07 февраля 2014

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

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

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

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

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

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

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

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

...