libusb에서 C++ 래퍼 연습을 위해 글을 쓸 것입니다. 내 API가 기본 lib의 구현을 완전히 숨기고 싶습니다. 사용자가 실제로 libusb를 사용하고 있는지조차 알지 못합니다. 그래서 두 클래스를 만들었습니다 : Context
과 Device
. Device
은 open
메서드를 사용하여 Context
에서 만들어집니다.객체를 생성 할 때 클래스 관계가있는 적절한 캡슐화
그래서 :
//--- context.hpp -------------------
class Context final
{
public:
Context();
~Context();
std::unique_ptr<Device> open(uint16_t vid, uint16_t pid);
private:
struct Impl;
std::unique_ptr<Impl> impl;
};
//--- context.cpp -------------------
struct Context::Impl
{
libusb_context* ctx;
};
Context::Context()
: impl(std::make_unique<Impl>())
{ /* ... */ }
//--- device.hpp -------------------
class Device final
{
public:
Device();
~Device();
private:
struct Impl;
std::unique_ptr<Impl> _impl;
};
//--- device.cpp -------------------
struct Device::Impl
{
libusb_device_handle* handle;
}
Device::Device()
: _impl(std::make_unique<Impl>())
{}
이제 질문은 : 내가 어떻게 open
방법을 구현합니까? 구현에서 libusb_open_device_with_vid_pid
으로 전화하여 libusb_context*
이 내 Context::Impl
이고 핸들을 Device::Impl
에 저장해야합니다. 여기에 내가 생각했던 옵션입니다
- 내가
Context
에 대한 포인터를 복용Device
의 생성자를 만들 수는 있지만,Device
의 ctor에 함수를 호출libusb_context*
포인터에 액세스 할 수 없습니다; - 나는 포인트 번호 1을 따르고
Context::Impl
을 헤더에 넣고Device
을Context
의 친구로 만듭니다. 이것은 추한 것처럼 들리지만, libusb_context*
포인터를 사용하는Device
의 생성자를 만듭니다. 그러나 캡슐화를 해제하려고합니다. 사용자는 libusb 세부 정보를 보지 말아야합니다.Context
에native_handle
메서드를 추가하여 번호 1을 수행하고 구현 포인터를 얻을 수 있지만 숫자 3과 같은 문제가 발생합니다.- 나는
open
에 함수 호출을 만들지 만Device
을 초기화하려면libusb_device_handle*
을 얻으시겠습니까? 캡슐화를 깨고 그런 포인터를 가지고Device
의 ctor을 가질 수 없습니다.
사용자가 * context * 개체를 전혀 볼 필요가 있습니까? 그것은 단지'Device'에 대한 숨겨진 구현 정보일까요? 나는'libusb'에 익숙하지 않지만 문맥 타입 객체는 인스턴스 정보를 유지하기위한'C' 핸들이다. 'C++ '에서 동일한 작업이 클래스 내부에서 종종 수행되는 경우 - 클래스 객체 **는 자체 핸들입니다. – Galik
@Galik 컨텍스트마다 여러 장치가있을 수 있으며 여러 컨텍스트가있을 수 있습니다. –