gil*_*_bz 2 c c++ conditional-compilation inner-classes one-definition-rule
我有一个类想要在 C 和 C++ 之间共享,其中 C 只能将其作为指针获取。然而,因为它是一个内部类,所以不能向前声明。相反,这就是我们当前的代码在公共头文件中所做的事情:
#ifdef __cplusplus
class Container {
public:
class Object {
public:
int x;
};
};
typedef Container::Object * PObject;
#else
typedef void* PObject;
#endif
Run Code Online (Sandbox Code Playgroud)
这看起来违反了单一定义规则 (ODR),因为 C 和 C++ 使用#ifdef. 但因为这是一个指针,所以我不确定这是否会产生真正的问题。C 仅使用指针将其传递给 C++ 函数,它不会直接用它执行任何操作。例如公共头文件中的这段代码:
#ifdef __cplusplus
extern "C" {
#endif
int object_GetX(PObject pObject);
#ifdef __cplusplus
}
#endif /* __cplusplus */
Run Code Online (Sandbox Code Playgroud)
这就是我们在 C++ 文件中实现它的方式:
int object_GetX(PObject pObject) {
return pObject->x;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:
首先,类型别名指针通常会带来麻烦。
不要这样做。
其次,“内部”类是一个被过度使用的概念,所以我的第一反应是考虑它是否真的有必要。
如果有必要,您可以定义一个不透明的空类型并从中派生以实现某种类型安全:
在共享标头中:
struct OpaqueObject;
#ifdef __cplusplus
extern "C" {
#endif
int object_GetX(OpaqueObject* pObject);
#ifdef __cplusplus
}
#endif /* __cplusplus */
Run Code Online (Sandbox Code Playgroud)
在 C++ 头文件中:
struct OpaqueObject {};
class Container {
public:
class Object : public OpaqueObject {
public:
int x;
};
};
Run Code Online (Sandbox Code Playgroud)
执行:
int object_GetX(OpaqueObject* pObject) {
return static_cast<Container::Object*>(pObject)->x;
}
Run Code Online (Sandbox Code Playgroud)