4

假设我有以下结构:

struct A{
    int a;
} a;

struct B{
    A a;
    int b;
} b;

如何检查是否b属于类型B或是否b属于类型A

4

6 回答 6

12

你的意思是在运行时,给定一个void *指向一个或另一个的?不幸的是,这是不可能的;C 没有任何类型的运行时类型信息机制。

于 2012-06-05T20:16:21.217 回答
3

在编译时:

#define WARN_IF_DIFFERENT_STRUCT_TYPE_1(T, o) do { \
    T temp = (o);                                  \
    (void) temp;                                   \
} while (0)

例子:

struct B b;
/* will warn if b is not of struct A type */
WARN_IF_DIFFERENT_STRUCT_TYPE_1(struct A, b);  

使用typeofGNU 扩展将两个对象作为宏参数传递:

#define WARN_IF_DIFFERENT_STRUCT_TYPE_2(o1, o2) do { \
    typeof(o1) temp = (o2);                          \
    (void) temp;                                     \
} while (0)   

例子:

struct A a;
struct B b;
/* will warn if a and b are not the same struct type */
WARN_IF_DIFFERENT_STRUCT_TYPE_2(a, b);  
于 2012-06-05T20:57:29.190 回答
0

不,就 C 而言,数据只是一串位。如何使用和解释数据取决于程序员。

这就像 achar可以表示一个字符、一个正数或一个负数(或其他任何东西)。这取决于上下文以及程序员如何使用它。

于 2012-06-05T20:18:30.850 回答
0

不。与在运行时使用vtable维护类型关联的 C++ 不同,C 不提供运行时类型检查的方法。

一种可能的解决方法是将类型标识符分配为结构的第一个元素:

struct A {
    int type;
    int a;
} a; a.type = 'A';

struct B {
    int type;
    A a;
    int b;
} b; b.type = 'B';

// Now, given a (void*) pointer `ptr`, of either `A` or `B`...
if ( *(int*)ptr == 'A')
{
    // ...
}
elseif ( *(int*)ptr == 'B')
{
    // ...
}
于 2012-06-05T20:20:37.110 回答
0

如果您要编写自己的类型检查机制,我建议您编写宏来为您填写类型字段。

typedef struct A {
   void *type;
   int a; 
} A;

这个宏使用字符串化初始化每个结构的类型信息:

 #define InitializeType(ptr, type) \
      ((ptr)->type == (void *)(#type ## __FILE__ ##))
 #define IsType(ptr, type)      \
      ((ptr)!=NULL && (ptr)->type != (void *)(#type ## __FILE__ ##))

它使用包含结构名称及其所在文件的字符串填充类型字段。您可以在多个源文件中拥有两个同名的结构,但是您不能在其中拥有两个同名的结构相同的源文件,因此包含初始化类型的源文件的名称的原因。然后您可以像这样使用它们:

 A alpha;
 InitializeType(&alpha, A);
 IsType(&alpha, A);

不过有几个注意事项;您必须使用字符串池编译器标志,您必须将结构封装在“类”中,以便类型检查和初始化本地化到包含私有结构的源文件,并且您必须将 void *type 作为第一个参数每个结构。

于 2012-07-23T04:50:56.267 回答
-2

你能破解它吗?如果真的有必要并且你只有几个结构。

struct A{
    int a;
    int identifer = 0;
} a;

struct B{
    A a;
    int b;
    int identifer = 1;
} b;

如果你的代码你可以像

if object->identifer == 0 
     bla bla bla
于 2012-06-05T20:19:53.430 回答