我正在设计一个库,尝试在单个通用句柄(1)或一组通用句柄(2)下统一平台特定的细节。
为使问题更具体,我将提供两个实现的摘录和示例用法。
(1)带标签的联合;包罗万象的类型:
enum tb_handle_kind {};
/* These two are never exposed to the user: */
struct tb_dir {
struct _WIN32_FIND_DATAW find_data;
HANDLE search_handle;
};
struct tb_file {
HANDLE native_handle;
};
struct tb_handle {
enum tb_handle_kind kind;
union {
struct tb_file file;
struct tb_dir dir;
};
};
您将通过以下方式使用
file_open(struct tb_handle *, const char *);
handle_close(struct tb_handle *);
struct tb_handle file;
file_open(&file, "path/to/file");
...
handle_close(&file); /* No need for a cast, or a file-specfic function. */
(2)通用句柄作为其他人的基类:
struct tb_handle {
/* Fields shared by each handle. */
};
struct tb_dir {
struct tb_handle base; /* Now a "base class" of tb_dir. */
struct _WIN32_FIND_DATAW find_data;
HANDLE search_handle;
};
用法:
/* Either a pair of init/close functions. */
int dir_open(struct tb_dir *, const char *);
int dir_close(struct tb_dir *);
/* Or handle_close from the previous example, that now requires a cast: */
handle_close((struct tb_handle *) &some_dir);
据我所知,(1)提供了一种更容易使用的API,但以类型安全为代价,而(2)使更多的精神体操获得了更高的安全性(您不能将错误类型的句柄传递给功能)。
您更愿意从用户的角度使用哪个?