问题描述
有没有在具有C从不定义的结构有没有优惠?
Is there any benefit in having never-defined structures in C ?
例在SQLite的源$ C $ C:
Example in SQLite source code :
/* struct sqlite3_stmt is never defined */
typedef struct sqlite3_stmt sqlite3_stmt;
和对象被操纵,像这样:
And the object is manipulated like so :
typedef struct Vdbe Vdbe;
struct Vdbe {
/* lots of members */
};
int sqlite3_step(sqlite3_stmt *pStmt) {
Vdbe *v = (Vdbe*) pStmt;
/* do stuff with v... */
}
那么,为什么不直接使用通常的抽象类型,在 foo.c的
私下定义的实际来源结构和公共的typedef
在 foo.h中
头?
So why not just use a usual abstract type, with the actual structure privately defined in foo.c
source and a public typedef
in foo.h
header ?
推荐答案
要澄清:什么你问的就是为什么SQLite的确实不是这样做上面的:
To clarify: What you're asking is why SQLite does the above instead of doing this:
头文件:
typedef struct sqlite3_stmt sqlite3_stmt;
C文件:
struct sqlite3_stmt {
/* lots of members */
};
int sqlite3_step(sqlite3_stmt *pStmt) {
/* do stuff with pStmt... */
}
(这是KennyTM的回答联系到不透明指针模式的规范形式。)
(This is the canonical form of the "opaque pointer" pattern linked to in KennyTM's answer.)
唯一的好理由,我能想到的,为什么SQLite的做什么它做的是以下内容:
The only good reason I can think of why SQLite does what it does is the following:
后端code,我猜测,这个API来之前和使用的名称 VDBE
- 这个名字可能意味着相关沿实施的东西虚拟数据库条目的线路(疯狂猜测这里)。
The backend code, I'm speculating, came before the API and used the name Vdbe
-- the name probably means something related to the implementation along the lines of "virtual database entry" (guessing wildly here).
当时间到了创建API,有人意识到,需要通过 sqlite3_step
参数是一个 VDBE
但这是不完全,将传达很多API的用户的名称。因此,从用户的角度来看,一个 VDBE
被称为 sqlite3_stmt
。
When time came to create the API, someone realized that the parameter required by sqlite3_step
was a Vdbe
but that this was not exactly a name that would convey a lot to the user of the API. Hence, from the user's point of view, a Vdbe
is referred to as an sqlite3_stmt
.
这里的关键,那么,两个视图在同一项目的区分:后端认为在 VDBE
S(无论他们是)方面,因为这是一个名字这使得在实施的背景下意义。关于 sqlite3_stmt
是因为这是有意义的背景下一个名称的接口的。
The point here, then, is to differentiate between two views of the same item: The backend thinks in terms of Vdbe
s (whatever they are) because that's a name that makes sense in the context of the implementation. The API talks about sqlite3_stmt
s because that's a name that makes sense in the context of the interface.
编辑:由于Amarghosh指出,为什么不这样做,以达到同样的效果。
As Amarghosh points out, why not just do this to achieve the same effect?
typedef struct Vdbe sqlite3_stmt;
(请投他,我不不想在这里吸走他的REP):VDBE只有几种可能的后端之一;接口采用了通用 sqlite3_stmt
,这是再投对什么后端使用来实现它。
KennyTM points out a good possible reason (please vote him up, I don't want to siphon off his rep here): VDBE is only one of several possible backends; the interface uses a "generic" sqlite3_stmt
, and this is then cast to whatever the backend uses to implement it.
这篇关于从未定义结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!