3

type フィールド定義を持つ 2 つの異なる構造があります (以下を参照してください)。

struct A {
int type;
char type_a[8];
char random[8];
};


struct B {
int type;
char type_b[16];
char random[16];
};

ここで、タイプに基づいてこの 2 つの構造を区別したいので、たとえば

if (type == A)
struct A *a = (struct A *)buff;
if (type == B)
struct B *b = (struct B *)buff;

事前にバフで渡される構造の種類はわかりません。では、バフからタイプを抽出するにはどうすればよいですか。type フィールドは、両方の構造体の最初のフィールドであることが保証されています。

4

3 に答える 3

3

この種のことは、C の OOP デザイン パターンで行うことができます。

ここでの考え方は、Base構造体にはtypeメンバーがあるということです。構造AB「拡張」BaseBase構造体は と の両方の最初のメンバーであるAため、BどちらもキャストしBaseてそのまま使用できます。

これにより、 のインスタンスを使用する必要がある場合に、コンパイル時の型の安全性を確保しながら、Baseandの間でキャストする安全な方法が得られます。ABBase

typedef struct Base {
    int type;
} Base;

typedef struct A {
    Base base;
} A;

typedef struct B {
    Base base;
} B;

int ATYPE = 1;
int BTYPE = 2;

int getType(Base *base) {
    return base->type;
}

int _tmain(int argc, _TCHAR* argv[])
{
    A a;
    B b;
    B *bptr;
    Base *base;
    int baseType;

    a.base.type = ATYPE;
    b.base.type = BTYPE;

    base = (Base*)&b;

    baseType = getType(base);

    // something like this is reasonable,
    // since you know that base is an
    // instance of B.
    if (baseType == BTYPE) {
        bptr = (B*)base;
    }

    if (baseType != BTYPE) return -1;
    return 0;
}
于 2013-03-08T20:36:31.610 に答える
1

C には、このようなデータ構造の共用体機能があります。共用体は構造体に似ていますが、共用体の各メンバーは同じメモリ位置を占有します。type次に、構造体を解釈する方法を知ることができるように、次の例で別のフィールドを使用します。

これを使用すると、キャストをまったく行わずに問題に取り組み、コンパイル時の型の安全性を維持できます。

完全な例を次に示します。

#include <stdio.h>
#include <string.h>

#define TYPE_A 1
#define TYPE_B 2

struct A
{
    char member1[8];
    char member2[8];
};

struct B
{
    char member1[16];
    char member2[16];
};

struct base
{
    int type;
    union
    {
        struct A a;
        struct B b;
    } data;
};

char *get_member2(struct base *buff)
{
    if (buff->type == TYPE_A)
        return buff->data.a.member2;

    if (buff->type == TYPE_B)
        return buff->data.b.member2;

    return NULL;
}

int main(void)
{
    struct base b1;
    struct base b2;

    /* Set up test structs. */

    b1.type = TYPE_A;
    strcpy(b1.data.a.member2, "Hello");

    b2.type = TYPE_B;
    strcpy(b2.data.b.member2, "World");

    /* Print member2 from each struct. */

    printf("%s\n", get_member2(&b1));
    printf("%s\n", get_member2(&b2));

    return 0;
}

出力:

Hello
World

コード: コードパッド

于 2013-03-08T22:15:22.613 に答える
0

AとBを変更したくない/変更できないと仮定します:

#define TYPE_A 0
#define TYPE_B 1

...

struct *B create_B()
{  struct *B= malloc(sizeof B);
   B->type=TYPE_B;
   return B;
}

...

void *buff=create_B();

...

struct A a;
a.type=TYPE_A;
void *buff=&a;

...

struct A *a=NULL;
struct B *b=NULL;
int type = *((int *)buff);
if (type == TYPE_A)
 a = (struct A *)buff;
else if (type == TYPE_B)
   b = (struct B *)buff;

あなたのコードの問題は、 a と b のスコープが if 内にしかなく、おそらくもっと必要なことです。

于 2013-03-08T20:28:14.080 に答える