结构相互依赖 [英] struct interdependencies

查看:85
本文介绍了结构相互依赖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述




我在头文件中有两个结构,它们互相引用,

导致编译错误。有没有一种标准的方法可以解决这个问题?


typedef struct {

...

RtAction *行动;

} RtWidget;


typedef struct {

...

void(* action)(RtWidget * widget,XEvent * event);

} RtAction;

Hi,

I have two structs in a header file, and they reference each other,
causing a compile error. Is there a standard way to deal with this?

typedef struct {
...
RtAction *actions;
} RtWidget;

typedef struct {
...
void (*action)(RtWidget *widget, XEvent *event);
} RtAction;

推荐答案

2005年4月18日星期一00:07: 07 + 1000,Russell Shaw写道:
On Mon, 18 Apr 2005 00:07:07 +1000, Russell Shaw wrote:


我在头文件中有两个结构,它们相互引用,导致编译错误。有没有一种标准的方法来解决这个问题?

typedef struct {
...
RtAction * actions;
} RtWidget;
typedef struct {
...
void(* action)(RtWidget * widget,XEvent * event);
} RtAction;
Hi,

I have two structs in a header file, and they reference each other,
causing a compile error. Is there a standard way to deal with this?

typedef struct {
...
RtAction *actions;
} RtWidget;

typedef struct {
...
void (*action)(RtWidget *widget, XEvent *event);
} RtAction;




怎么样:


typedef struct RtAction * RtAction;

typedef struct RtWidget * RtWidget;


struct RtWidget {

...

RtAction动作;

};


struct RtAction {

...

void(* action)(RtWidget小部件,XEvent *事件);

};


Rob Gamble



How about this:

typedef struct RtAction * RtAction;
typedef struct RtWidget * RtWidget;

struct RtWidget {
...
RtAction actions;
};

struct RtAction {
...
void (*action)(RtWidget widget, XEvent *event);
};

Rob Gamble


文章< b5 ************ @ main.anatron.com.au>

Russell Shaw< rjshawN_o@s_pam.netspace.net.au>写道:
In article <b5************@main.anatron.com.au>
Russell Shaw <rjshawN_o@s_pam.netspace.net.au> wrote:
我在头文件中有两个结构,它们互相引用,导致编译错误。有没有一种标准的方法来解决这个问题?

typedef struct {
...
RtAction * actions;
} RtWidget;
typedef struct {
...
void(* action)(RtWidget * widget,XEvent * event);
} RtAction;
I have two structs in a header file, and they reference each other,
causing a compile error. Is there a standard way to deal with this?

typedef struct {
...
RtAction *actions;
} RtWidget;

typedef struct {
...
void (*action)(RtWidget *widget, XEvent *event);
} RtAction;




是的。停止使用typedef。


我很认真。他们不会在这里给你买太多,而且 - 通过误导

你 - 是你大部分悲伤的原因。 Typedef没有定义

类型。 "结构"关键字定义类型(后跟{,或

标签和{)。你有两个类型定义的结构上面的关键字。


你*必须*在这里使用至少一个结构标签,因为结构

标签可以声明为不完整的类型并用于 ;转发

参考"时尚。一旦你有了标签,你就不需要

typedef。


struct RtAction; / * forward-declareRtAction输入* /

struct RtWidget; / * forward-declareRtWidget类型* /


struct RtWidget {/ *重新声明,现在定义,RtWidget输入* /

...

struct RtAction * actions; / *指的是更早的forward-decl * /

};


struct RtAction {/ *定义RtAction输入* /

...

void(* action)(struct RtWidget *,XEvent *);

};


(显然你可以消除至少一个转发

声明。由于定义总是一个声明,

无论哪个实际定义是第一位的 - 在这种情况下

" struct RtWidget {" - 不需要先前的声明。

在这个*特定*的情况下,你可以实际上放弃了前进

声明,但是如果你先定义RtAction类型

,你需要RtWidget的前向声明

类型,由于有点愚蠢,虽然自然,范围规则。)


现在,如果你有一些理由你必须坚持使用那些无用的

typedef关键字只是为了避免写出C'的类型关键字

(即STRangely-spelled用户定义的abstraCt类型或struct)

稍后,注意一旦你有一个前向声明的结构,你可以为
做一个typedef别名:


struct forward_declared_type;


typedef struct forward_declared_type another_name_for_it;


/ *

*现在:

* struct forward_declared_type * p;

*和:

* another_name_for_it * q;

*将p和q声明为指向不完整类型的指示

*其真实名称是forward_declared_type。

*标识符" another_name_for_it"只是

*真实姓名的别名。

* /


当然,你可以将两者合二为一大混乱(typedef

总是弄得一团糟:-))与通常的组合交易:


typedef struct forward_declared_type another_name_for_it;


重要的是使用C'的类型关键字(即struct)

带有标签,以便您可以在以后再次定义时重复该类型的名称:


struct forward_declared_type {

...内容......

};


无标签,struct {开始定义一个新的,不同的,
未命名类型,而不是定义(完成)早期的

不完整类型。


注意:


typedef struct {...}别名;


定义一个新类型(" struct {...没有名字,并且可以再次引用
,但是然后捕获无名。用别名键入

。出于讨论目的,我们可以将

第一个无名称类型称为



Yes. Stop using typedefs.

I am serious. They are not buying you much here, and -- by misleading
you -- are the cause of most of your grief. Typedefs do not define
types. "struct" keywords define types (when followed by "{", or
a tag and "{"). You have two type-defining "struct" keywords above.

You *must* use at least one structure tag here, because structure
tags can be declared as incomplete types and to be used in "forward
reference" fashion. Once you have the tags, you do not need the
typedefs.

struct RtAction; /* forward-declare the "RtAction" type */
struct RtWidget; /* forward-declare the "RtWidget" type */

struct RtWidget { /* re-declare, and now define, the "RtWidget" type */
...
struct RtAction *actions; /* refers to earlier forward-decl */
};

struct RtAction { /* define the "RtAction" type */
...
void (*action)(struct RtWidget *, XEvent *);
};

(Obviously you can eliminate at least one of the "forward
declarations". Since a definition is always also a declaration,
whichever actual definition comes first -- in this case
"struct RtWidget {" -- does not need a previous declaration.
In this *particular* case, you can actually drop both forward
declarations, but if you were to define the RtAction type
first, you would need the forward declaration for the RtWidget
type, due to somewhat silly, albeit "natural", scope rules.)

Now, if you have some reason you must insist on using those useless
"typedef" keywords just to avoid writing out C''s "type" keyword
(i.e., "STRangely-spelled User-defined abstraCt Type" or "struct")
later, note that once you have forward-declared a structure, you
can then make a typedef alias for it:

struct forward_declared_type;

typedef struct forward_declared_type another_name_for_it;

/*
* now:
* struct forward_declared_type *p;
* and:
* another_name_for_it *q;
* declare p and q as pointers to the incomplete type
* whose "true name" is "forward_declared_type". The
* identifier "another_name_for_it" is just an alias for
* the real name.
*/

Of course, you can combine the two into one big mess (typedefs
always make a mess :-) ) with the usual combo deal:

typedef struct forward_declared_type another_name_for_it;

The important thing is to use C''s "type" keyword (i.e., "struct")
with a tag, so that you can repeat the name of the type when you
go to define it later:

struct forward_declared_type {
... contents ...
};

Without the tag, "struct {" starts defining a new, different,
unnamed type, instead of defining ("completing") the earlier
incomplete type.

Note that:

typedef struct { ... } alias;

defines a new type ("struct { ... }") that has no name and can
never be referred-to again, but then captures the "no-name" type
with the alias. For discussion purposes, we might refer to the
first no-name type as "


compiler_generated_name
compiler_generated_name


这篇关于结构相互依赖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆