typedef指针好吗?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了typedef指针好吗?相关的知识,希望对你有一定的参考价值。
我浏览了一些代码,发现约定是将指针类型变成类似
SomeStruct*
进入
typedef SomeStruct* pSomeStruct;
这有什么好处吗?
当指针本身可以被视为“黑匣子”,即内部表示与代码无关的一条数据时,这是适当的。
本质上,如果您的代码将从不取消引用指针,而您只是将其传递给API函数(有时通过引用),那么typedef不仅会减少代码中*
的数量,而且还会减少也向程序员建议不要真的干预指针。
这也使将来需要时更容易更改API。例如,如果您更改为使用ID而不是指针(反之亦然),则现有代码不会中断,因为从一开始就不应该将指针取消引用。
如果这样做,由于编译器读取:您将无法创建const pSomeStruct的STL容器:
list<const pSomeStruct> structs;
as
list<SomeStruct * const> structs;
由于元素不可分配,因此不是合法的STL容器。
参见此 question 。
编号
与const
混合后,将使您的生活变得痛苦不堪
typedef foo *fooptr;
const fooptr bar1;
const foo *bar2
bar1
和bar2
是否为同一类型?
[是的,我只是引用赫伯·萨特的上师。他说了很多实话。 ;)
-编辑-
将链接添加到引用的文章。
http://www.drdobbs.com/conversationsa-midsummer-nights-madness/184403835
Win32 API几乎对每个结构(如果不是全部)都执行此操作
POINT => *LPPOINT
WNDCLASSEX => *LPWNDCLASSEX
RECT => *LPRECT
PRINT_INFO_2 => *LPPRINT_INFO_2
这很好,它保持一致,但是在我看来,它并没有增加任何优雅。
typedef的目的是隐藏实现细节,但是typedef-ing指针属性隐藏太多,并使代码更难于阅读/理解。因此,请不要这样做。
如果要隐藏实现细节(通常是一件好事,请不要隐藏指针部分。以标准FILE
接口的原型为例:
FILE *fopen(const char *filename, const char *mode);
char *fgets(char *s, int size, FILE *stream);
这里fopen将pointer返回到某些结构FILE
(您不知道其实现细节)。也许FILE
并不是一个很好的例子,因为在这种情况下,它可以与某些pFILE类型一起使用,从而隐藏了它是指针的事实。
pFILE fopen(const char *filename, const char *mode);
char *fgets(char *s, int size, pFILE stream);
但是,这只会起作用,因为您永远不会弄乱直接指向的内容。根据我的经验,当您键入一些指针并在某些地方修改代码时,将变得非常难以阅读。
前段时间,我会对此问题回答“否”。现在,随着智能指针的兴起,不再总是用星号“ *”来定义指针。因此,关于类型是否为指针没有明显的认识。
所以现在我要说:只要明确指出它是“指针类型”,就可以使用typedef指针。这意味着您必须专门为其使用前缀/后缀。不,例如,“ p”不是足够的前缀。我可能会选择“ ptr”。
不是我的经验。隐藏'*
'使代码难以阅读。
我唯一一次在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);
即SignalFunction
是指向带有两个参数(int
和SigCatcher
)并返回SigCatcher
的函数的指针。并且signal()
本身是一个接受两个参数(int
和SigCatcher
)并返回SigCatcher
的函数。
这可以帮助您避免某些错误。例如下面的代码:
int* pointer1, pointer2;
pointer2不是int *,它很简单int。但是使用typedef不会发生:
typedef int* pInt;
pInt pointer1, pointer2;
它们现在都是int *。
我的回答是明确的“否”。
为什么?
首先,您只需将单个字符*
替换为另一个单个字符p
。那就是零增益。仅此一项就不能阻止您这样做,因为做多余的事情总是毫无意义的。
第二,这是重要原因,*
带有不好掩饰的含义。如果我将某些东西传递给这样的函数
void foo(SomeType bar);
void baz() {
SomeType myBar = getSomeType();
foo(myBar);
}
我不希望通过将其传递给myBar
来更改foo()
的含义。毕竟,我按值传递,所以foo()
只会看到myBar
的副本吗?当SomeType
别名表示某种指针时不可以!
这同时适用于C指针和C ++智能指针:如果您隐藏它们是指向用户的指针的事实,则会造成混乱,这是完全不必要的。因此,请不要为您的指针加上别名。
(我相信类型定义指针类型的习惯只是一种错误的尝试,即隐藏一个程序员http://wiki.c2.com/?ThreeStarProgrammer拥有多少颗星星。]
这是风格问题。您在Windows头文件中经常看到这种代码。尽管他们倾向于全部使用大写字母而不是小写字母p作为前缀。
我个人避免使用typedef。让用户明确说他们想要Foo *比PFoo更清楚。 Typedef现在最适合使STL可读:)
typedef stl::map<stl::wstring,CAdapt<CComPtr<IFoo>> NameToFooMap;
(与许多答案一样)取决于。
在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.
Typedef用于使代码更具可读性,但是将指针作为typedef将增加混乱。最好避免使用typedef指针。
讨论以假定的语言为C进行。没有考虑C ++的分支。
为未标记的结构使用指针typedef
问题Size of a struct that is defined as a pointer提出了将typedef
用于(结构)指针的有趣观点。
考虑无标签混凝土(非不透明)结构类型定义:
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
时必须定义结构的详细信息。
这是只能与动态内存分配一起使用的类型。
这是一种无名的类型。指向结构类型的指针具有名称,但是结构类型本身没有名称。
如果要强制执行动态分配,这似乎是一种方法。
但是,总的来说,比开悟更容易引起混乱和焦虑。
摘要
通常,使用typedef
定义指向无标签结构类型的指针是个坏主意。
以上是关于typedef指针好吗?的主要内容,如果未能解决你的问题,请参考以下文章