具有低冗长度的C泛型继承

时间:2018-06-18 19:03:41

标签: c unions

有:

struct packet_sample_t {
   int common_id;
   int some;
   char data[];
   float foo;
}

具有以下功能:

void dispatch_packet(void *packet);

我的目标是解æžæ•°æ®åŒ…ID,然åŽè°ƒç”¨å…¶å¤„ç†ç¨‹åºï¼Œä½†æˆ‘无法从common_id检索结构å˜é‡void *。

我想在高级语言中创建类似interface的内容,å‡è®¾æˆ‘的所有数æ®åŒ…结构都应该包å«å˜é‡common_id。 所以我正在寻找一些åƒä¸‹é¢é‚£æ ·å·¥ä½œçš„东西:

struct packet_base {
   int common_id;
}

void dispatch_packet(void *packet) {
   int common_id = ( (packet_base *)packet )->common_id;
   switch(common_id) {...}
}

void test() {
   packet_sample_t packet = {.common_id = 10, ...};
   dispatch_packet((void *) &packet); //this function should retrieve `common_id`

   packet_other_t other = {.common_id = 1};
   dispatch_packet((void *) &other); // again with another packet
}

我对C语言并ä¸ç†Ÿæ‚‰ï¼Œæˆ‘真的ä¸çŸ¥é“如何åšåˆ°è¿™ä¸€ç‚¹ã€‚但简å•æ¥è¯´ï¼Œæˆ‘希望能够将数æ®åŒ…转å‘到其packet_base,它们共享一个公共å˜é‡ã€‚

编辑:示例中的更多细节

2 个答案:

答案 0 :(得分:1)

您的技术有效。有a number of ways to do struct inheritance in C,这就是其中之一。 21st Century Cå¯èƒ½å¯¹æ‚¨å’ŒObject-Oriented Programming with ANSI C都很好。

您对如何声明和使用结构和类型有疑问。让我们æ¥çœ‹çœ‹ã€‚

struct packet_base {
   int common_id;
};

è¿™ç§ç±»åž‹ä¸ºstruct packet_base。如果è¦å£°æ˜ŽæŒ‡å‘此类型的指针,则需è¦ç¼–写struct packet_base *packet。如果您想è¦æŠ•å°„此类型的å˜é‡ï¼Œåˆ™(struct packet_base *)thing。

这很烦人,所以你通常使用typedef为结构声明一个类型别å。语法为typedef <type> <alias>

typedef struct {
   int common_id;
} packet_base_t;

表示类型struct { int common_id; }的别å为packet_base_t。现在您å¯ä»¥ä½¿ç”¨packet_base_t作为类型。 packet_base_t *packet声明一个指针和(packet_base_t *)thing强制转æ¢ã€‚

通过修å¤ï¼ŒåŠ ä¸Šä¸€äº›å°é”™è¯¯ï¼Œå®ƒå¯ä»¥æ­£å¸¸å·¥ä½œã€‚有关char *data vs char data[]çš„ä¿¡æ¯ï¼Œè¯·å‚阅What is the difference between char array vs char pointer in C?。

typedef struct {
   int common_id;
   int some;
   char *data;
   float foo;
} packet_sample_t;

typedef struct {
   int common_id;
} packet_base_t;

void dispatch_packet(void *arg) {
    // It's simpler to cast to a new variable once then to muck
    // up the code with casts.
    packet_base_t *packet = (packet_base_t *)arg;

    int common_id = packet->common_id;
    printf("id: %d\n", common_id);
}

答案 1 :(得分:0)

您å¯ä»¥ä½¿ç”¨union在å•ä¸ªç»“构中èšåˆä¸åŒç±»åž‹çš„æ•°æ®

struct packet1_t
{
   // Packet1 specific data
   ......
}

struct packet2_t
{
   // Packet2 specific data
   ......
}

struct packet_t
{
    int common_id;
    union
    {
        struct packet1_t packet1;
        struct packet2_t packet2;
        ......
    }
} packet;

现在,根æ®ID,您å¯ä»¥ä»Žè”åˆä¸­é€‰æ‹©æ­£ç¡®çš„类型:

int do_something_with_packet(packet_t packet)
{
    switch (packet.common_id)
    {
        case 1:
            do_something_with_packet1(packet.packet1);
            break;
        case 2:
            do_something_with_packet2(packet.packet2);
            break;
        ..................
    }
    ....
}