我记得我曾经看到某些代码曾经有一个结构作为基类,而C ++类作为派生类
struct Base_Struct
{
}
class Derived : Base_Struct
{
...
}
关键是指向Base_Struct *的指针从C ++文件传递到某些C文件,然后设法使用Base_Struct中的一些函数指针。
我的问题是:如果我将Base_Struct *传递给C文件,C代码是否能够完全使用Base_Struct?派生类怎么样?
答案 0 :(得分:3)
如果我将
Base_Struct*
传递给C文件,C代码是否可以完全使用Base_Struct
?
如果它是标准布局类,并且C编译器对C ++编译器等类使用相同的ABI,则它可以访问所有数据成员。显然,它无法访问任何成员函数或静态成员,因为C中不存在这样的东西,并且必须省略任何C兼容的结构定义。
派生类怎么样?
您无法在C程序中定义该类,因此它无法对指针执行任何有趣的操作。
答案 1 :(得分:1)
也许它可以用于基类。但这是非常特殊的情况:
但它会直接从不派生类。
但是这会产生很多限制,我会提供一个C级API来分配操作那些在“void *”上定义为别名的指针(我甚至不确定你能在纯C中做这样的别名)。 / p>
类似的东西:
typedef void* BaseStructPtr;
BaseStructPtr AllocateBase(/* constructor params */);
BaseStructPtr AllocateDerived(/* constructor params */);
TypeOfField1 GetField1(BaseStructPtr ptr);
TypeOfField2 GetField2(BaseStructPtr ptr);
/* etc... */
答案 2 :(得分:1)
我认为从C:
中声明的结构派生没有任何问题<强> C / C ++ 强>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
int a;
int b;
} X;
void print(struct StructX* x) {
printf("%d, %d\n", x->a, x->b);
}
#ifdef __cplusplus
} // extern "C"
#endif
<强> C ++ 强>
#include <iostream>
struct Y : StructX {
int c;
Y()
: c(3)
{
a = 1;
b = 2;
}
void print() {
::print(this);
std::cout << c << std::endl;
}
};
int main() {
Y y;
y.print();
}
使用C ++声明结构会使事情变得复杂。 现在结构可能(或将会)有C不知道的信息和(比方说) memcpy可能会引入未定义的行为。为了避免这种情况,你必须这样做 用C:
包装C ++结构的功能<强> C / C ++ 强>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct Z; // An opaque type (for X) to ensure minimum type safety.
extern int a(Z*);
extern int b(Z*);
#ifdef __cplusplus
} // extern "C"
#endif
<强> C ++ 强>
extern "C" {
int a(Z* z) {
return ((X*)z)->a;
}
int b(Z* z) {
return ((X*)z)->b;
}
} // extern "C"
答案 3 :(得分:1)
在您的示例中,是的,C编译器将能够使用Base_Struct *指针和访问成员。您可以在C和CPP文件中使用相同的结构定义而不会出现问题。只要是为C文件转换结构的Cpp,编译器就可以完成这项工作。
void Give_Typed_Pointer_to_C_Function(Base_Struct* pStruct) {...}
void Give_Pointer_to_C_Function(void* pStruct) {...}
Base_Struct A;
Derived B;
Give_Typed_Pointer_to_C_Function(&A); // OK
Give_Typed_Pointer_to_C_Function(&B); // OK
Give_Pointer_to_C_Function(&A); // OK
Give_Pointer_to_C_Function(&B); // wrong
Give_Pointer_to_C_Function((Base_Struct*)&B); // OK
为了实现这个目的,你必须使用相同的对齐和包装结构,但是当你传递指针时,我认为你是同一个项目所以它应该已经是这样了。
如果你按照相同的顺序保持结构,你甚至可以做更多事情
struct S1 { int x;
int y;
};
class C1 { int x;
int y;
int add(int,int);
};
void Give_Typed_Pointer_to_C_Function(S1 *pStruct);
C1 object;
Give_Typed_Pointer_to_C_Function((S1*)&object); // OK
// an safer alternative as you can't have to be sure that S1 and C1 match
struct C1 { int x;
int y;
#ifdef __cplusplus
int add(int,int);
#endif
};
如果你把Cpp关键字像class / public / private和struct一样放在struct中。如果你不使用继承,它也会起作用。