我查看了一些代码,发现约定是将指针类型转换为
SomeStruct*
进入
typedef SomeStruct* pSomeStruct;
有什么好处吗?
我查看了一些代码,发现约定是将指针类型转换为
SomeStruct*
进入
typedef SomeStruct* pSomeStruct;
有什么好处吗?
Answers:
当指针本身可以视为“黑匣子”时,即内部数据与代码无关的一条数据时,这可能是适当的。
本质上,如果您的代码永远不会取消引用指针,而只是将其传递给API函数(有时通过引用),则typedef不仅会减少*
代码中的s数量,而且还会向程序员建议指针不应真的不喜欢。
如果需要的话,这也使得将来更容易更改API。例如,如果更改为使用ID而不是指针(反之亦然),则现有代码不会中断,因为从一开始就不应该取消指针的引用。
FILE*
没有进行类型定义是因为不透明的指针,是为了允许诸如getc()
和的宏putc()
直接操作FILE结构,并且在大多数情况下避免了函数调用的开销。
根据我的经验。隐藏' *
'使代码难以阅读。
Device
并且您typedef
指向Device_Ptr
(而不是必须使用Device *
)或类似指针,则它非常可读。我看到很多成熟的,相当大的库可以做到这一点。尤其是在C ++中,如果添加模板,则可以省去很多打字的麻烦。
myTypePtr
或myTypeRef
超过那颗星星。:P
我唯一在typedef中使用指针的时间是在处理指向函数的指针时:
typedef void (*SigCatcher(int, void (*)(int)))(int);
typedef void (*SigCatcher)(int);
SigCatcher old = signal(SIGINT, SIG_IGN);
否则,我发现它们比帮助更令人困惑。
signal()
函数而不是信号捕获器的指针的正确类型。可以SigCatcher
通过编写以下内容使它更清晰(使用上面的更正类型):
typedef SigCatcher (*SignalFunction)(int, SigCatcher);
或者,声明signal()
函数:
extern SigCatcher signal(int, SigCatcher);
也就是说,aSignalFunction
是指向带有两个参数(anint
和a SigCatcher
)并返回a的函数的指针SigCatcher
。并且signal()
它本身是一个函数,它接受两个参数(anint
和a SigCatcher
)并返回a SigCatcher
。
sig_t
与my匹配SigCatcher
,是的,它signal()
极大地简化了声明。
这可以帮助您避免一些错误。例如下面的代码:
int* pointer1, pointer2;
pointer2不是int *,它是简单的int。但是使用typedef不会发生:
typedef int* pInt;
pInt pointer1, pointer2;
它们现在都是int *。
int *p1 = NULL, *p2 = NULL;
*
无关紧要。
我的回答是明确的“否”。
为什么?
好吧,首先,您只需将一个字符替换*
为另一个字符p
。那是零增益。仅凭这一点就可以避免这样做,因为做多余的事情总是毫无意义的。
其次,这是重要的原因,将*
进行这意味着不好躲。如果我将某些东西传递给这样的功能
void foo(SomeType bar);
void baz() {
SomeType myBar = getSomeType();
foo(myBar);
}
我不希望通过将的含义myBar
更改为foo()
。毕竟,我是按照价值传递的,所以foo()
只有看到myBar
权利的副本吗?不是什么时候SomeType
别名就意味着某种指针!
这适用于C指针和C ++智能指针:如果您隐藏它们是指向用户的指针这一事实,则会造成不必要的混乱。因此,请不要为指针加上别名。
(我相信类型定义指针类型的习惯只是一种误导的尝试,即隐藏一个程序员http://wiki.c2.com/?ThreeStarProgrammer拥有多少颗星星。)
void *vp=/*...*/; foo(vp);
或不会提供类型系统保护foo(0);
。(用于枚举的Typedef和用于永远不会显示为数字的事物的数字typedef具有类似的问题)。
它(像很多答案一样)取决于。
在C语言中,这很常见,因为您试图掩盖对象是指针。您试图暗示这是所有函数都操作的对象(我们知道它是下面的指针,但它表示您正在操作的对象)。
MYDB db = MYDBcreateDB("Plop://djdjdjjdjd");
MYDBDoSomthingWithDB(db,5,6,7);
CallLocalFuc(db); // if db is not a pointer things could be complicated.
MYDBdestroyDB(db);
MYDB下方可能是某个对象的指针。
在C ++中,这不再是必需的。
主要是因为我们可以通过引用传递东西,并且方法被合并到类声明中。
MyDB db("Plop://djdjdjjdjd");
db.DoSomthingWithDB(5,6,7);
CallLocalFuc(db); // This time we can call be reference.
db.destroyDB(); // Or let the destructor handle it.
没有。
当你与之融合时,它将使你的生活痛苦不堪 const
typedef foo *fooptr;
const fooptr bar1;
const foo *bar2
是bar1
和bar2
相同类型的吗?
是的,我只是引用赫伯·萨特的大师。她说了很多实话。;)
-编辑-
将链接添加到引用的文章。
http://www.drdobbs.com/conversationsa-midsummer-nights-madness/184403835
假定感兴趣的语言是C进行了讨论。尚未考虑C ++的分支。
定义为指针的结构的大小问题对使用typedef
for(结构)指针提出了有趣的看法。
考虑无标签的混凝土(不是不透明的)结构类型定义:
typedef struct { int field1; double field2; } *Information;
成员的详细信息与讨论完全相切;重要的是这不是像这样的不透明类型typedef struct tag *tag;
(并且您不能通过不typedef
带标签的来定义这种不透明类型)。
提出的问题是“如何找到该结构的大小”?
简短的答案是“仅通过类型的变量”。没有可用于的标签sizeof(struct tag)
。例如,您不能有用地编写,并且sizeof(*Information)
sizeof(Information *)
是指向指针类型的指针的大小,而不是结构类型的大小。
实际上,如果要分配这样的结构,则只能通过动态分配(或模拟动态分配的替代技术)来创建。无法创建称为指针的结构类型的局部变量Information
,也无法创建static
结构类型的文件范围(全局或)变量,也无法嵌入此类结构(例如与指向此类结构的指针相反)转换为另一种结构或联合类型。
您可以-必须-写:
Information info = malloc(sizeof(*info));
除了将指针隐藏在中之外typedef
,这是一个好习惯-如果info
更改类型,则大小分配将保持准确。但是在这种情况下,这也是获取结构大小和分配结构的唯一方法。并且没有其他方法可以创建该结构的实例。
这取决于您的目标。
这不是不透明的类型-当指针类型为typedef
'd时,必须定义结构的详细信息。
这是只能与动态内存分配一起使用的类型。
这是一种无名的类型。指向结构类型的指针具有名称,但是结构类型本身没有名称。
如果要强制执行动态分配,这似乎是一种方法。
但是,总的来说,它比启蒙更容易引起混乱和焦虑。
通常,typedef
定义一个无标签结构类型的指针是一个坏主意。
Win32 API几乎对每个结构(如果不是全部)都执行此操作
POINT => *LPPOINT
WNDCLASSEX => *LPWNDCLASSEX
RECT => *LPRECT
PRINT_INFO_2 => *LPPRINT_INFO_2
保持一致很不错,但是我认为它并没有增加任何优雅。
LP
代表长指针,简写表示法LPPOINT ptr;
不过是方便的缩写POINT FAR *ptr;
,FAR
扩展到far
,然后扩展到__far
。所有这一切都相当微不足道,但过去更糟。
typedef的目的是隐藏实现细节,但是typedef-ingpointer属性隐藏太多,使代码更难以阅读/理解。所以请不要那样做。
如果要隐藏实现细节(通常是一件好事),请不要隐藏指针部分。以标准FILE
接口的原型为例:
FILE *fopen(const char *filename, const char *mode);
char *fgets(char *s, int size, FILE *stream);
在这里,fopen返回一个指向某些结构的指针FILE
(您不知道其实现细节)。也许FILE
不是一个很好的例子,因为在这种情况下,它可以使用某些pFILE类型来隐藏它是指针的事实。
pFILE fopen(const char *filename, const char *mode);
char *fgets(char *s, int size, pFILE stream);
但是,这只会起作用,因为您永远不会弄乱直接指向的内容。根据我的经验,在您键入一些指针并在某些地方修改代码的那一刻变得很难阅读。
前一段时间,我会对这个问题回答“否”。现在,随着智能指针的兴起,指针不再总是用星号“ *”定义。因此,关于类型是否为指针没有明显的认识。
所以现在我要说:只要明确指出它是“指针类型”,就可以使用typedef指针。这意味着您必须专门为其使用前缀/后缀。不,例如,“ p”不是足够的前缀。我可能会选择“ ptr”。