Unk*_*own 68 c c++ pointers typedef conventions
我查看了一些代码并发现惯例是将指针类型转换为
SomeStruct*
Run Code Online (Sandbox Code Playgroud)
成
typedef SomeStruct* pSomeStruct;
Run Code Online (Sandbox Code Playgroud)
这有什么好处吗?
Art*_*ius 100
当指针本身可以被视为"黑盒子"时,这是适当的,即,其内部表示应该与代码无关的一段数据.
本质上,如果您的代码永远不会取消引用指针,并且您只是将其传递给API函数(有时通过引用),那么不仅typedef减少了*
代码中的s 数量,而且还向程序员建议指针不应该真的被插手了.
如果需要,这也可以在将来更容易地更改API.例如,如果您更改为使用ID而不是指针(反之亦然),现有代码将不会中断,因为指针永远不应该首先被解除引用.
Jon*_*ler 28
我在typedef中使用指针的唯一一次是处理指向函数的指针时:
typedef void (*SigCatcher(int, void (*)(int)))(int);
Run Code Online (Sandbox Code Playgroud)
typedef void (*SigCatcher)(int);
SigCatcher old = signal(SIGINT, SIG_IGN);
Run Code Online (Sandbox Code Playgroud)
否则,我发现它们比有用更令人困惑.
signal()
函数的指针的正确类型,而不是信号捕获器的指针.SigCatcher
通过编写可以使其更清晰(使用上面更正的类型):
typedef SigCatcher (*SignalFunction)(int, SigCatcher);
Run Code Online (Sandbox Code Playgroud)
或者,声明signal()
函数:
extern SigCatcher signal(int, SigCatcher);
Run Code Online (Sandbox Code Playgroud)
也就是说,a SignalFunction
是一个指向函数的指针,该函数接受两个参数(a int
和a SigCatcher
)并返回a SigCatcher
.而signal()
本身是有两个参数(一个函数int
和一个SigCatcher
)并返回SigCatcher
.
Sad*_*per 14
这可以帮助您避免一些错误.例如,在以下代码中:
int* pointer1, pointer2;
Run Code Online (Sandbox Code Playgroud)
pointer2不是int*,它是简单的int.但是对于typedef,这不会发生:
typedef int* pInt;
pInt pointer1, pointer2;
Run Code Online (Sandbox Code Playgroud)
他们现在都是int*.
cma*_*ter 12
我的回答是明确的"不".
为什么?
好吧,首先,你只需要*
为另一个角色交换一个角色p
.这是零增益.仅此一点就应该让你不要这么做,因为做一些没有意义的额外的东西总是很糟糕.
其次,这就是重要的原因,隐藏着不好的*
携带意义.如果我将某些东西传递给这样的函数
void foo(SomeType bar);
void baz() {
SomeType myBar = getSomeType();
foo(myBar);
}
Run Code Online (Sandbox Code Playgroud)
我不希望myBar
通过传递它来改变它的含义foo()
.毕竟,我正在经历价值,所以foo()
只能看到一份myBar
正确的副本?不是什么时候SomeType
别名意味着某种指针!
这适用于C指针和C++智能指针:如果你隐藏它们指向用户的事实,你将产生完全不必要的混淆.所以,请不要别指你的指针.
(我相信typedefing指针类型的习惯只是误导了一个程序员http://wiki.c2.com/?ThreeStarProgrammer隐藏了多少个星星.)
假设感兴趣的语言是 C 进行讨论。尚未考虑对 C++ 的影响。
\n\n定义为指针的结构的大小问题引发了关于使用(结构)指针的有趣侧面typedef
。
考虑无标签具体(非不透明)结构类型定义:
\n\ntypedef struct { int field1; double field2; } *Information;\n
Run Code Online (Sandbox Code Playgroud)\n\n成员的详细信息与本次讨论完全无关;重要的是这不是一个不透明类型typedef struct tag *tag;
(并且您不能通过typedef
不带标签的 a 来定义此类不透明类型)。
提出的问题是“如何找到该结构的大小”?
\n\n简短的答案是“仅通过该类型的变量”。没有可与 一起使用的标签sizeof(struct tag)
。例如,您不能有效地编写, andsizeof(*Information)
sizeof(Information *)
是指向指针类型的指针的大小,而不是结构类型的大小。
事实上,如果您想分配这样的结构,除非通过动态分配(或模仿动态分配的代理技术),否则无法创建一个结构。没有办法创建其指针被调用的结构类型的局部变量Information
,也没有办法创建static
结构类型的文件范围(全局或)变量,也没有办法嵌入这样的结构(如与指向此类结构的指针相反)到另一个结构或联合类型。
你可以\xe2\x80\x94必须\xe2\x80\x94写:
\n\nInformation info = malloc(sizeof(*info));\n
Run Code Online (Sandbox Code Playgroud)\n\n除了指针隐藏在 中这一事实之外typedef
,这是一个很好的做法 \xe2\x80\x94\xc2\xa0 如果类型发生info
变化,大小分配将保持准确。但在这种情况下,它也是获取结构体大小并分配结构体的唯一方法。并且没有其他方法可以创建该结构的实例。
这取决于你的目标。
\n\n这不是不透明类型\xe2\x80\x94,当指针类型为typedef
\'d 时,必须定义结构的详细信息。
它是一种只能与动态内存分配一起使用的类型。
\n\n这是一种无名的类型。指向结构类型的指针有名称,但结构类型本身没有名称。
\n\n如果你想强制动态分配,这似乎是一种方法。
\n\n但总的来说,它比启蒙更有可能引起困惑和焦虑。
\n\n一般来说,使用typedef
定义指向无标记结构类型的指针是一个坏主意。
这是一种风格问题.您在Windows头文件中经常看到这种代码.虽然他们倾向于选择全部大写版本,而不是使用小写p作为前缀.
我个人避免使用typedef.让用户明确表示他们想要一个Foo*比PFoo更清楚.Typedef最适合这些天使STL可读:)
typedef stl::map<stl::wstring,CAdapt<CComPtr<IFoo>> NameToFooMap;
Run Code Online (Sandbox Code Playgroud)
它(像许多答案一样)取决于.
在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);
Run Code Online (Sandbox Code Playgroud)
在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.
Run Code Online (Sandbox Code Playgroud)
不。
与它混在一起的那一刻,它会让你的生活变得悲惨 const
typedef foo *fooptr;
const fooptr bar1;
const foo *bar2
Run Code Online (Sandbox Code Playgroud)
是bar1
和bar2
同类型吗?
是的,我只是在引用 Herb Sutter 的 Guru。她说了很多实话。;)
- 编辑 -
添加引用文章的链接。
http://www.drdobbs.com/conversationsa-midsummer-nights-madness/184403835