我正在爲實踐編寫一個C++包裝器,用於libusb。我想讓我的API完全隱藏底層庫的實現:用戶甚至不應該知道我實際上在使用libusb。所以我創建了兩個類:Context
和Device
。 A 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
,這將執行我的Context::Impl
的libusb_context*
並將句柄存儲在Device::Impl
中。下面是我想選擇:
- 我創建的
Device
一個構造函數採用指針來Context
,但Device
的構造函數沒有訪問libusb_context*
指針調用的函數; - 我遵循第一點,並將
Context::Impl
放在標題中並使Device
成爲Context
的朋友:儘管這聽起來很醜陋, - 我創建了一個
Device
的構造函數,它需要一個libusb_context*
指針:但我會打破封裝,用戶應該不會看到libusb的細節; - 我添加一個
native_handle
方法到Context
,所以我可以做第一個並獲得實現指針,但導致與第三個相同的問題。 - 我在
open
中進行函數調用,但是如何將Device
初始化爲我得到的libusb_device_handle*
?我不能有一個Device
ctor這樣的指針,打破封裝。
用戶是否需要查看* context *對象?難道這只是一個隱藏的'Device'的實現細節?我對'libusb'不熟悉,但經常上下文類型的對象是維護實例信息的'C'句柄。在'C++'中,相同的工作通常在類的內部完成 - 類對象**是**自己的句柄。 – Galik
@Galik每個上下文可以有多個設備,並且可以有多個上下文。 –