| |
4.自标识结构体
在强类型语言中,如果使用非法的数据类型将会导致运行时错误。但对于弱类型语言,比如C语言,在指针的传递和类型转换过程中,很容易把类型混淆。为此,我们引入类似于强类型语言中的运行时类型检验思想。
现在我们通过实例来讲解自标识结构体,具体代码如下所示:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#define TARGET_MARKER_SIG 0xFAF32000
typedef struct {
unsigned int signature;
unsigned int targetType;
double x, y, z;
} targetMarker_t;
#define INIT_TARGET_MARKER(ptr) \
((( targetMarker_t *)ptr)->signature = TARGET_MARKER_SIG)
#define CHECK_TARGET_MARKER(ptr) \
assert(((targetMarker_t *)ptr)->signature == \
TARGET_MARKER_SIG)
void displayTarget( targetMarker_t *target )
{
/* 预先检查 target结构体 */
CHECK_TARGET_MARKER(target);
printf( "Target type is %d\n", target->targetType );
return;
}
int main()
{
void *object1, *object2;
/* 新建两个对象 */
object1 = (void *)malloc( sizeof(targetMarker_t) );
assert(object1);
object2 = (void *)malloc( sizeof(targetMarker_t) );
assert(object2);
/*按照target marker结构体初始化object1 */
INIT_TARGET_MARKER(object1);
/* 尝试显示object1 */
displayTarget( (targetMarker_t *)object1 );
/* 尝试显示object2 */
displayTarget( (targetMarker_t *)object2 );
return 0;
}
在代码的第6-12行,定义了我们的目标结构体,其中有一个专门的头部,名为signature(识别标志),即该结构类型的运行时类型标识符。并且在第4行为该类型定义了一个识别标志,作为该结构类型的唯一描述符号。此外,代码中还提供了两个宏INIT_TARGET_MARKER和CHECK_TARGET_MARKER,分别用来初始化和检验该结构体中的识别标志。
继续往后看,请注意代码的34-54行,其中分配了两个等同长度(targetMarker_t)的内存空间来供两个对象使用,然后利用宏INIT_TARGET_MARKER将其中一个初始化,最后,分别利用displayTarget函数显示。
对于第22-31行的displayTarget函数,首先调用CHECK_TARGET_MARKER来检验收到的对象的识别标志,如果该标志非法,assert就会发挥作用。当然,这里只是一个概念性的演示。 |
|