C中的opaque(抽象)数据类型

blu*_*tic 0 c types abstract

文件api.h

#include <stdio.h>
#ifndef API
#define API

struct trytag;
typedef struct trytag try;

void trial (try *);

#endif
Run Code Online (Sandbox Code Playgroud)

文件core.h

#ifndef CORE
#define CORE
struct trytag
{
    int a;
    int b;
};
#endif
Run Code Online (Sandbox Code Playgroud)

文件func.c

#include "api.h"
#include "core.h"

void trial (try *tryvar)
{
    tryvar->a = 1;
    tryvar->b = 2;
}
Run Code Online (Sandbox Code Playgroud)

文件main.c

#include "api.h"

int main ()
{
    try s_tryvar;

    trial(&s_tryvar);

    printf("a = %d\nb = %d\n", s_tryvar.a, s_tryvar.b);
}
Run Code Online (Sandbox Code Playgroud)

当我编译时,我得到:

main.c:5: error: storage size of ‘s_tryvar’ isn’t known
Run Code Online (Sandbox Code Playgroud)

如果我core.hmain.c此错误中包含,则不会尝试定义core.h.但我希望try隐藏结构main.c- 它不应该知道try结构的成员.我错过了什么?

Car*_*rum 6

我不认为你想做的事情是可能的.编译器需要知道编译的try结构有多大main.c.如果你真的希望它是不透明的,那么创建一个通用指针类型,而不是直接声明变量main(),make alloc_try()free_try()函数来处理创建和删除.

像这样的东西:

api.h:

#ifndef API
#define API

struct trytag;
typedef struct trytag try;

try *alloc_try(void);
void free_try(try *);
int try_a(try *);
int try_b(try *);
void trial (try *);

#endif
Run Code Online (Sandbox Code Playgroud)

core.h:

#ifndef CORE
#define CORE
struct trytag
{
    int a;
    int b;
};
#endif
Run Code Online (Sandbox Code Playgroud)

func.c:

#include "api.h"
#include "core.h"
#include <stdlib.h>

try *alloc_try(void)
{
    return malloc(sizeof(struct trytag));
}

void free_try(try *t)
{
    free(t);
}

int try_a(try *t)
{
    return t->a;
}

int try_b(try *t)
{
    return t->b;
}

void trial(try *t)
{
    t->a = 1;
    t->b = 2;
}
Run Code Online (Sandbox Code Playgroud)

main.c中:

#include <stdio.h>
#include "api.h"

int main()
{
    try *s_tryvar = alloc_try();

    trial(s_tryvar);
    printf("a = %d\nb = %d\n", try_a(s_tryvar), try_b(s_tryvar));

    free_try(s_tryvar);
}
Run Code Online (Sandbox Code Playgroud)

  • 哎呀,不要做"typedef void try;".当你这样做时,你会失去类型安全性(编译器将无法捕获像int x; trial(&x)这样的废话;`引入新结构的问题技巧要好得多. (3认同)
  • 关于分配实例的部分是正确的,但我想知道main.c应该如何取消引用a和b,当它只有api.h而不是core.h时.我不认为没有func.c会暴露一些访问助手方法. (2认同)