如果我没记错的话。这段代码应该有用。
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
int a;
} Base;
typedef struct {
int a;
} Derived;
void Init(Base* b) {
b->a = 1;
}
#ifdef __cplusplus
}
#endif
int main() {
Derived d;
Init(&d); // error can not convert argument 1 from 'Derived *' to 'Base *'
}
它编译为C源(没有extern“C”)。如何在不修改C部分的情况下将其编译为C ++?
编辑:我修改了代码,以便它可以在C和C ++中实际复制和测试。
答案 0 :(得分:4)
它在C中编译(同时生成警告),因为在C世界中更容易接受类型滥用。编制者通常允许违反标准。
在C ++中,您需要reinterpret_cast
指针:
Init(reinterpret_cast<Base*>(&d));
或
Init((Base*)&d);
理想情况下,您希望将此指针滥用封装到最小的可维护功能或类中。
答案 1 :(得分:2)
您的Derived
名称具有误导性。您没有从Derived
派生Base
,而C中的结构等价并不重要。它可以与强制转换一起使用,但是你必须在没有编译器帮助的情况下保持这种等价。有一天你决定改变Base
定义
typedef struct {
int a;
int c; /* New field */
} Base;
您必须修改所有“派生”定义。
在C中,导出通常是通过嵌入来模拟的:
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
int a;
} Base;
typedef struct {
Base base;
} Derived;
void Init(Base* b) {
b->a = 1;
}
#ifdef __cplusplus
}
#endif
int main() {
Derived d;
Init(&d.base);
}