对于当前的C ++项目,我使用来自第三方的外部库(1个大标头)。此头提供了多个类似C的函数来驱动硬件。为了使其更易于在C ++中使用,我编写了一个C ++类来包装这些函数,并使用pimpl实现隐藏此标头。
这些功能的某些参数由其主标头中的预处理器指令#define
定义。我想在包装类之外使用这些参数的值,但不包含此标头。
我试图在我的C ++类中使用前向声明的枚举。但是我的枚举成员在定义它们的源文件之外不可用
external_lib.h
#define PARAM_A_VAL_0 0
#define PARAM_A_VAL_1 1
bool external_function_param_a(int param_a);
wrapper.h
class wrapper
{
enum PARAM_A : int;
...
bool SetParamA(wrapper::PARAM_A a);
}
wrapper.cpp
#include <wrapper.h>
#include <external_lib.h>
enum wrapper::PARAM_A: int
{
VAL_0 = PARAM_A_VAL_0,
VAL_1 = PARAM_A_VAL_1
};
bool wrapper SetParamA(wrapper::PARAM_A a)
{
return external_function_param_a(a);
}
main.cpp
#include <wrapper.h>
int main()
{
wrapper w;
w.SetParamA(wrapper::PARAM_A::VAL_0);
// compilation error : VAL_0 not a member of wrapper::PARAM_A
}
我的解决方案是否有问题,或者这个想法是不可能的?有没有更好的解决方案。在类包装器中创建很多成员似乎不是一个好主意,也不是在所有函数成员中都启用枚举。
答案 0 :(得分:3)
如果必须保持编译时的一致性,就无法避免包含外部标头,如this Q&A中所述。
如果编译时常数不是必需的,则可以分隔wrapper::PARAM_A::VAL_NNN
常量的声明和定义,如下所示:
标题:
struct wrapper {
class PARAM_A {
int val;
PARAM_A(int val) : val(val) {}
friend class ::wrapper;
public:
static const PARAM_A VAL_0;
static const PARAM_A VAL_1;
};
bool SetParamA(wrapper::PARAM_A a);
};
实施:
const wrapper::PARAM_A wrapper::PARAM_A::VAL_0 = wrapper::PARAM_A(PARAM_A_VAL_0);
const wrapper::PARAM_A wrapper::PARAM_A::VAL_1 = wrapper::PARAM_A(PARAM_A_VAL_1);
bool wrapper::SetParamA(wrapper::PARAM_A a)
{
return external_function_param_a(a.val);
}
现在,API的使用与您的示例相同:
wrapper w;
w.SetParamA(wrapper::PARAM_A::VAL_0);
w.SetParamA(wrapper::PARAM_A::VAL_1);
请注意类PARAM_A
隐藏int
值的方式:由于它不再是enum
,因此不再可以直接使用int
来代替,所以对external_function_param_a
的调用需要“解包”该值。