I looked through some code and noticed that the convention was to turn pointer types like
我查看了一些代码,发现规则是像这样转换指针类型
SomeStruct*
into
成
typedef SomeStruct* pSomeStruct;
Is there any merit to this?
这有什么好处吗?
13 个解决方案
#1
90
This can be appropriate when the pointer itself can be regarded as a "black box", that is, a piece of data whose internal representation should be irrelevant to the code.
当指针本身可以被视为“黑盒”时,这是合适的,也就是说,一个内部表示应该与代码无关的数据块。
Essentially, if your code will never dereference the pointer, and you just pass it around API functions (sometimes by reference), then not only does the typedef reduce the number of *
s in your code, but also suggests to the programmer that the pointer shouldn't really be meddled with.
本质上,如果您的代码永远不会撤销指针的引用,并且您只是通过API函数(有时是通过引用)传递它,那么typedef不仅会减少代码中的*s数量,而且还会向程序员建议,指针实际上不应该受到干扰。
This also makes it easier to change the API in the future if the need arises, for instance using an ID rather than a pointer (or vice versa). Since the pointer was never supposed to be dereferenced in the first place, existing code won't break.
这也使得在将来如果需要时更容易更改API,例如使用ID而不是指针(反之亦然)。由于最初不应该取消对指针的引用,所以现有的代码不会中断。
#2
65
Not in my experience. Hiding the '*
' makes the code hard to read.
以我的经验。隐藏“*”会使代码难以阅读。
#3
25
The only time I use a pointer inside the typedef is when dealing with pointers to functions:
我唯一一次在typedef中使用指针是在处理指向函数的指针时:
typedef void (*SigCatcher(int, void (*)(int)))(int);
typedef void (*SigCatcher)(int);
SigCatcher old = signal(SIGINT, SIG_IGN);
Otherwise, I find them more confusing than helpful.
否则,我觉得它们更让人困惑而不是有帮助。
The struck-out declaration is the correct type for a pointer to the
signal()
function, not of the signal catcher. It could be made clearer (using the corrected SigCatcher
type above) by writing: typedef SigCatcher (*SignalFunction)(int, SigCatcher);
Or, to declare the signal()
function:
或声明信号()函数:
extern SigCatcher signal(int, SigCatcher);
That is, a SignalFunction
is a pointer to a function which takes two arguments (an int
and a SigCatcher
) and returns a SigCatcher
. And signal()
itself is a function which takes two arguments (an int
and a SigCatcher
) and returns a SigCatcher
.
也就是说,SignalFunction是指向一个函数的指针,该函数接受两个参数(int和SigCatcher)并返回一个SigCatcher。signal()本身是一个函数,它接受两个参数(int和SigCatcher)并返回一个SigCatcher。
#4
16
This can help you avoid some errors. For example in following code:
这可以帮助您避免一些错误。例如以下代码:
int* pointer1, pointer2;
pointer2 is not an int *, it is simple int. But with typedefs this is not gonna happen:
pointer2不是int *,它是简单的int.但是对于typedefs,这不会发生:
typedef int* pInt;
pInt pointer1, pointer2;
They are both int * now.
它们现在都是int *。
#5
5
It (like so many answers) depends.
这(像很多答案一样)要看情况而定。
In C this is very common as you are trying to disguise that an object is a pointer. You are trying to imply that this is the object that all your functions manipulate (we know it is a pointer underneath but it represents the object you are manipulating).
在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);
Underneath MYDB is probably a pointer at some object.
在MYDB下面可能是指向某个对象的指针。
In C++ this is no longer required.
Mainly because we can pass things around by reference and the methods are incorporated into the class declaration.
在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.
#6
4
This is a matter of style. You see this kind of code very frequently in the Windows header files. Though they tend to prefer the all upper case version instead of prefixing with a lower case p.
这是一个风格问题。您经常在Windows头文件中看到这种代码。尽管他们倾向于使用大写字母而不是小写字母p作为前缀。
Personally I avoid this use of typedef. It's much clearer to have the user explicitly say they want a Foo* than PFoo. Typedef's are best suited these days for making STL readable :)
我个人避免使用这种类型定义。让用户明确地说他们想要一个Foo*比PFoo更清楚。如今,Typedef最适合于使STL可读:)
typedef stl::map<stl::wstring,CAdapt<CComPtr<IFoo>> NameToFooMap;
#7
4
Typedef is used to make code more readable, but making pointer as typedef will increase confusion. Better to avoid typedef pointers.
Typedef用于使代码更具可读性,但是将指针设置为Typedef将增加混淆。最好避免使用类型定义指针。
#8
3
If you do this, you will be unable to create STL containers of const pSomeStruct since the compiler reads:
如果这样做,您将无法创建const pSomeStruct的STL容器,因为编译器是:
list<const pSomeStruct> structs;
as
作为
list<SomeStruct * const> structs;
which is not a legal STL container since the elements are not assignable.
这不是一个合法的STL容器,因为元素是不可分配的。
See this question .
看到这个问题。
#9
3
My answer is a clear "No".
我的回答是“不”。
Why?
为什么?
Well, first of all, you simply exchange a single character *
for another single character p
. That is zero gain. This alone should keep you from doing this as it is always bad to do extra stuff that's pointless.
首先,你只需用一个字符*交换另一个字符p,这是零增益。只有这样,你才能避免这样做,因为做一些没有意义的额外工作总是不好的。
Second, and that is the important reason, the *
carries meaning that is not good to hide. If I pass something to a function like this
第二,这是一个重要的原因,*承载的意义是不好隐藏的。如果我把一些东西传递给这样的函数。
void foo(SomeType bar);
void baz() {
SomeType myBar = getSomeType();
foo(myBar);
}
I do not expect the meaning of myBar
to be changed by passing it to foo()
. After all, I'm passing by value, so foo()
only ever sees a copy of myBar
right? Not when SomeType
is aliased to mean some kind of pointer!
我不希望通过传递myBar到foo()来更改它的含义。毕竟,我是通过值传递的,所以foo()只会看到myBar的一个副本,对吧?当某类型被转译为某种指针时就不是这样了!
This applies both to C pointers and C++ smart pointers: If you hide the fact that they are pointers to your users, you will create confusion that is totally unnecessary. So, please, don't alias your pointers.
这既适用于C指针,也适用于c++智能指针:如果隐藏它们是指向用户的指针这一事实,就会造成完全不必要的混乱。所以,请不要给你的指针起别名。
(I believe the habit of typedefing pointer types is just a misguided attempt to hide how many stars one has as a programmer http://wiki.c2.com/?ThreeStarProgrammer .)
(我认为输入指针类型的习惯只是一种错误的尝试,试图隐藏作为程序员的人有多少个星星。http://wiki.c2.com/?ThreeStarProgrammer)。
#10
2
Win32 API does this with just about every structure (if not all)
Win32 API对几乎所有的结构(如果不是全部的话)都这样做
POINT => *LPPOINT
WNDCLASSEX => *LPWNDCLASSEX
RECT => *LPRECT
PRINT_INFO_2 => *LPPRINT_INFO_2
It's nice how it is consistent, but in my opinion it doesn't add any elegance.
它的一致性很好,但在我看来它并没有增加任何优雅。
#11
1
Some time ago, i'd have answered "no" to this question. Now, with the rise of smart pointers, pointers are not always defined with a star '*' anymore. So there is nothing obvious about a type being a pointer or not.
不久前,我对这个问题的回答是“不”。现在,随着智能指针的兴起,指针不再总是用*来定义。因此,类型是否为指针并不明显。
So now i'd say : it is fine to typedef pointers, as long as it is made very clear that it is a "pointer type". That means you have to use a prefix/suffix specifically for it. No, "p" is not a sufficient prefix, for instance. I'd probably go with "ptr".
所以现在我要说:定义指针是可以的,只要它是一个“指针类型”就可以了。这意味着你必须使用前缀/后缀。例如,“p”并不是一个足够的前缀。我可能会选择ptr。
#12
1
Discussion pitched assuming the language of interest is C. Ramifications for C++ have not been considered.
假设感兴趣的语言是C.还没有考虑c++的分支。
Using a a pointer typedef for an untagged structure
The question Size of a struct that is defined as a pointer raises an interesting side-light on using typedef
for (structure) pointers.
定义为指针的结构体的问题大小引发了使用typedef处理(结构)指针的有趣问题。
Consider the tagless concrete (not opaque) structure type definition:
考虑无标签的具体(不是不透明)结构类型定义:
typedef struct { int field1; double field2; } *Information;
The details of the members are completely tangential to this discussion; all that matters is that this not an opaque type like typedef struct tag *tag;
(and you can't define such opaque types via a typedef
without a tag).
成员的细节与这次讨论完全无关;重要的是这不是一个不透明的类型,比如typedef struct标签*标签;(如果没有标记,就不能通过typedef定义这种不透明类型)。
The question raised is 'how can you find the size of that structure'?
人们提出的问题是,“如何才能找到这种结构的大小?”
The short answer is 'only via a variable of the type'. There is no tag to use with sizeof(struct tag)
. You can't usefully write , for example, and sizeof(*Information)
sizeof(Information *)
is the size of a pointer to the pointer type, not the size of the structure type.
简短的回答是“仅通过类型的变量”。使用sizeof(struct tag)没有标签。例如,不能有效地编写sizeof(*Information),而sizeof(Information *)是指向指针类型的指针的大小,而不是结构类型的大小。
In fact, if you want to allocate such a structure, you can't create one except via dynamic allocation (or surrogate techniques that mimic dynamic allocation). There is no way to create a local variable of the structure type whose pointers are called Information
, nor is there a way to create a file scope (global or static
) variable of the structure type, nor is there a way to embed such a structure (as opposed to a pointer to such a structure) into another structure or union type.
事实上,如果您想要分配这样的结构,除了通过动态分配(或者模拟动态分配的代理技术),您不能创建这样的结构。没有办法创建一个局部变量的指针的结构类型被称为信息,也没有一种方法来创建一个文件范围(全局或静态)变量的结构类型,也没有这样的方式嵌入结构(相对于这样一个结构的指针)到另一个结构或联合类型。
You can — must — write:
你可以——必须——写下:
Information info = malloc(sizeof(*info));
Apart from the fact that the pointer is hidden in the typedef
, this is good practice — if the type of info
changes, the size allocation will remain accurate. But in this case, it is also the only way to get the size of the structure and to allocate the structure. And there's no other way to create an instance of the structure.
除了指针隐藏在typedef中这一事实之外,这是一个很好的实践——如果信息类型改变,大小分配将保持准确。但在这种情况下,它也是获得结构尺寸和分配结构的唯一方法。没有其他方法来创建这个结构的实例。
Is this harmful?
It depends on your goals.
这取决于你的目标。
This isn't an opaque type — the details of the structure must be defined when the pointer type is typedef
'd.
这不是一个不透明的类型——当指针类型为typedef时,必须定义结构的细节。
It is a type that can only be used with dynamic memory allocation.
它是一种只能用于动态内存分配的类型。
It is a type that is nameless. The pointer to the structure type has a name, but the structure type itself does not.
这是一种无名的类型。指向结构类型的指针有一个名称,但是结构类型本身没有。
If you want to enforce dynamic allocation, this seems to be a way to do it.
如果您想强制执行动态分配,这似乎是一种方法。
On the whole, though, it is more likely to cause confusion and angst than enlightenment.
但总的来说,它更有可能造成困惑和焦虑,而不是启迪。
Summary
It is, in general, a bad idea to use typedef
to define a pointer to a tagless stucture type.
一般来说,使用typedef定义指向无标记结构类型的指针是个坏主意。
#13
-1
The purpose with typedef is to hide the implementation details, but typedef-ing the pointer property hides too much and makes the code harder to read/understand. So please do not do that.
typedef的目的是隐藏实现细节,但是typedef-ing指针属性隐藏太多,使代码更难读/理解。所以请不要这样做。
If you want to hide implementation details (which often is a good thing to do), do not hide the pointer part. Take for instance at the prototype for the standard FILE
interface:
如果您想隐藏实现细节(这通常是一件好事),不要隐藏指针部分。以标准文件接口的原型为例:
FILE *fopen(const char *filename, const char *mode);
char *fgets(char *s, int size, FILE *stream);
here fopen returns a pointer to some structure FILE
(which you do not know the implementation details for). Maybe FILE
is not such a good example because in this case it could have worked with some pFILE type that hid the fact that it is a pointer.
这里fopen返回指向某个结构文件的指针(您不知道实现细节)。也许FILE不是一个很好的例子,因为在这种情况下,它可以使用某种pFILE类型来隐藏它是一个指针的事实。
pFILE fopen(const char *filename, const char *mode);
char *fgets(char *s, int size, pFILE stream);
However, that would only work because you never mess around with the content that is pointed to directly. The moment you typedef some pointer that you some places modify the code becomes very hard to read in my experience.
然而,这只会起作用,因为您永远不会对直接指向的内容造成混乱。在我的经验中,当您键入某个指针,表示您在某些地方修改了代码时,就会变得非常难以阅读。
#1
90
This can be appropriate when the pointer itself can be regarded as a "black box", that is, a piece of data whose internal representation should be irrelevant to the code.
当指针本身可以被视为“黑盒”时,这是合适的,也就是说,一个内部表示应该与代码无关的数据块。
Essentially, if your code will never dereference the pointer, and you just pass it around API functions (sometimes by reference), then not only does the typedef reduce the number of *
s in your code, but also suggests to the programmer that the pointer shouldn't really be meddled with.
本质上,如果您的代码永远不会撤销指针的引用,并且您只是通过API函数(有时是通过引用)传递它,那么typedef不仅会减少代码中的*s数量,而且还会向程序员建议,指针实际上不应该受到干扰。
This also makes it easier to change the API in the future if the need arises, for instance using an ID rather than a pointer (or vice versa). Since the pointer was never supposed to be dereferenced in the first place, existing code won't break.
这也使得在将来如果需要时更容易更改API,例如使用ID而不是指针(反之亦然)。由于最初不应该取消对指针的引用,所以现有的代码不会中断。
#2
65
Not in my experience. Hiding the '*
' makes the code hard to read.
以我的经验。隐藏“*”会使代码难以阅读。
#3
25
The only time I use a pointer inside the typedef is when dealing with pointers to functions:
我唯一一次在typedef中使用指针是在处理指向函数的指针时:
typedef void (*SigCatcher(int, void (*)(int)))(int);
typedef void (*SigCatcher)(int);
SigCatcher old = signal(SIGINT, SIG_IGN);
Otherwise, I find them more confusing than helpful.
否则,我觉得它们更让人困惑而不是有帮助。
The struck-out declaration is the correct type for a pointer to the
signal()
function, not of the signal catcher. It could be made clearer (using the corrected SigCatcher
type above) by writing: typedef SigCatcher (*SignalFunction)(int, SigCatcher);
Or, to declare the signal()
function:
或声明信号()函数:
extern SigCatcher signal(int, SigCatcher);
That is, a SignalFunction
is a pointer to a function which takes two arguments (an int
and a SigCatcher
) and returns a SigCatcher
. And signal()
itself is a function which takes two arguments (an int
and a SigCatcher
) and returns a SigCatcher
.
也就是说,SignalFunction是指向一个函数的指针,该函数接受两个参数(int和SigCatcher)并返回一个SigCatcher。signal()本身是一个函数,它接受两个参数(int和SigCatcher)并返回一个SigCatcher。
#4
16
This can help you avoid some errors. For example in following code:
这可以帮助您避免一些错误。例如以下代码:
int* pointer1, pointer2;
pointer2 is not an int *, it is simple int. But with typedefs this is not gonna happen:
pointer2不是int *,它是简单的int.但是对于typedefs,这不会发生:
typedef int* pInt;
pInt pointer1, pointer2;
They are both int * now.
它们现在都是int *。
#5
5
It (like so many answers) depends.
这(像很多答案一样)要看情况而定。
In C this is very common as you are trying to disguise that an object is a pointer. You are trying to imply that this is the object that all your functions manipulate (we know it is a pointer underneath but it represents the object you are manipulating).
在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);
Underneath MYDB is probably a pointer at some object.
在MYDB下面可能是指向某个对象的指针。
In C++ this is no longer required.
Mainly because we can pass things around by reference and the methods are incorporated into the class declaration.
在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.
#6
4
This is a matter of style. You see this kind of code very frequently in the Windows header files. Though they tend to prefer the all upper case version instead of prefixing with a lower case p.
这是一个风格问题。您经常在Windows头文件中看到这种代码。尽管他们倾向于使用大写字母而不是小写字母p作为前缀。
Personally I avoid this use of typedef. It's much clearer to have the user explicitly say they want a Foo* than PFoo. Typedef's are best suited these days for making STL readable :)
我个人避免使用这种类型定义。让用户明确地说他们想要一个Foo*比PFoo更清楚。如今,Typedef最适合于使STL可读:)
typedef stl::map<stl::wstring,CAdapt<CComPtr<IFoo>> NameToFooMap;
#7
4
Typedef is used to make code more readable, but making pointer as typedef will increase confusion. Better to avoid typedef pointers.
Typedef用于使代码更具可读性,但是将指针设置为Typedef将增加混淆。最好避免使用类型定义指针。
#8
3
If you do this, you will be unable to create STL containers of const pSomeStruct since the compiler reads:
如果这样做,您将无法创建const pSomeStruct的STL容器,因为编译器是:
list<const pSomeStruct> structs;
as
作为
list<SomeStruct * const> structs;
which is not a legal STL container since the elements are not assignable.
这不是一个合法的STL容器,因为元素是不可分配的。
See this question .
看到这个问题。
#9
3
My answer is a clear "No".
我的回答是“不”。
Why?
为什么?
Well, first of all, you simply exchange a single character *
for another single character p
. That is zero gain. This alone should keep you from doing this as it is always bad to do extra stuff that's pointless.
首先,你只需用一个字符*交换另一个字符p,这是零增益。只有这样,你才能避免这样做,因为做一些没有意义的额外工作总是不好的。
Second, and that is the important reason, the *
carries meaning that is not good to hide. If I pass something to a function like this
第二,这是一个重要的原因,*承载的意义是不好隐藏的。如果我把一些东西传递给这样的函数。
void foo(SomeType bar);
void baz() {
SomeType myBar = getSomeType();
foo(myBar);
}
I do not expect the meaning of myBar
to be changed by passing it to foo()
. After all, I'm passing by value, so foo()
only ever sees a copy of myBar
right? Not when SomeType
is aliased to mean some kind of pointer!
我不希望通过传递myBar到foo()来更改它的含义。毕竟,我是通过值传递的,所以foo()只会看到myBar的一个副本,对吧?当某类型被转译为某种指针时就不是这样了!
This applies both to C pointers and C++ smart pointers: If you hide the fact that they are pointers to your users, you will create confusion that is totally unnecessary. So, please, don't alias your pointers.
这既适用于C指针,也适用于c++智能指针:如果隐藏它们是指向用户的指针这一事实,就会造成完全不必要的混乱。所以,请不要给你的指针起别名。
(I believe the habit of typedefing pointer types is just a misguided attempt to hide how many stars one has as a programmer http://wiki.c2.com/?ThreeStarProgrammer .)
(我认为输入指针类型的习惯只是一种错误的尝试,试图隐藏作为程序员的人有多少个星星。http://wiki.c2.com/?ThreeStarProgrammer)。
#10
2
Win32 API does this with just about every structure (if not all)
Win32 API对几乎所有的结构(如果不是全部的话)都这样做
POINT => *LPPOINT
WNDCLASSEX => *LPWNDCLASSEX
RECT => *LPRECT
PRINT_INFO_2 => *LPPRINT_INFO_2
It's nice how it is consistent, but in my opinion it doesn't add any elegance.
它的一致性很好,但在我看来它并没有增加任何优雅。
#11
1
Some time ago, i'd have answered "no" to this question. Now, with the rise of smart pointers, pointers are not always defined with a star '*' anymore. So there is nothing obvious about a type being a pointer or not.
不久前,我对这个问题的回答是“不”。现在,随着智能指针的兴起,指针不再总是用*来定义。因此,类型是否为指针并不明显。
So now i'd say : it is fine to typedef pointers, as long as it is made very clear that it is a "pointer type". That means you have to use a prefix/suffix specifically for it. No, "p" is not a sufficient prefix, for instance. I'd probably go with "ptr".
所以现在我要说:定义指针是可以的,只要它是一个“指针类型”就可以了。这意味着你必须使用前缀/后缀。例如,“p”并不是一个足够的前缀。我可能会选择ptr。
#12
1
Discussion pitched assuming the language of interest is C. Ramifications for C++ have not been considered.
假设感兴趣的语言是C.还没有考虑c++的分支。
Using a a pointer typedef for an untagged structure
The question Size of a struct that is defined as a pointer raises an interesting side-light on using typedef
for (structure) pointers.
定义为指针的结构体的问题大小引发了使用typedef处理(结构)指针的有趣问题。
Consider the tagless concrete (not opaque) structure type definition:
考虑无标签的具体(不是不透明)结构类型定义:
typedef struct { int field1; double field2; } *Information;
The details of the members are completely tangential to this discussion; all that matters is that this not an opaque type like typedef struct tag *tag;
(and you can't define such opaque types via a typedef
without a tag).
成员的细节与这次讨论完全无关;重要的是这不是一个不透明的类型,比如typedef struct标签*标签;(如果没有标记,就不能通过typedef定义这种不透明类型)。
The question raised is 'how can you find the size of that structure'?
人们提出的问题是,“如何才能找到这种结构的大小?”
The short answer is 'only via a variable of the type'. There is no tag to use with sizeof(struct tag)
. You can't usefully write , for example, and sizeof(*Information)
sizeof(Information *)
is the size of a pointer to the pointer type, not the size of the structure type.
简短的回答是“仅通过类型的变量”。使用sizeof(struct tag)没有标签。例如,不能有效地编写sizeof(*Information),而sizeof(Information *)是指向指针类型的指针的大小,而不是结构类型的大小。
In fact, if you want to allocate such a structure, you can't create one except via dynamic allocation (or surrogate techniques that mimic dynamic allocation). There is no way to create a local variable of the structure type whose pointers are called Information
, nor is there a way to create a file scope (global or static
) variable of the structure type, nor is there a way to embed such a structure (as opposed to a pointer to such a structure) into another structure or union type.
事实上,如果您想要分配这样的结构,除了通过动态分配(或者模拟动态分配的代理技术),您不能创建这样的结构。没有办法创建一个局部变量的指针的结构类型被称为信息,也没有一种方法来创建一个文件范围(全局或静态)变量的结构类型,也没有这样的方式嵌入结构(相对于这样一个结构的指针)到另一个结构或联合类型。
You can — must — write:
你可以——必须——写下:
Information info = malloc(sizeof(*info));
Apart from the fact that the pointer is hidden in the typedef
, this is good practice — if the type of info
changes, the size allocation will remain accurate. But in this case, it is also the only way to get the size of the structure and to allocate the structure. And there's no other way to create an instance of the structure.
除了指针隐藏在typedef中这一事实之外,这是一个很好的实践——如果信息类型改变,大小分配将保持准确。但在这种情况下,它也是获得结构尺寸和分配结构的唯一方法。没有其他方法来创建这个结构的实例。
Is this harmful?
It depends on your goals.
这取决于你的目标。
This isn't an opaque type — the details of the structure must be defined when the pointer type is typedef
'd.
这不是一个不透明的类型——当指针类型为typedef时,必须定义结构的细节。
It is a type that can only be used with dynamic memory allocation.
它是一种只能用于动态内存分配的类型。
It is a type that is nameless. The pointer to the structure type has a name, but the structure type itself does not.
这是一种无名的类型。指向结构类型的指针有一个名称,但是结构类型本身没有。
If you want to enforce dynamic allocation, this seems to be a way to do it.
如果您想强制执行动态分配,这似乎是一种方法。
On the whole, though, it is more likely to cause confusion and angst than enlightenment.
但总的来说,它更有可能造成困惑和焦虑,而不是启迪。
Summary
It is, in general, a bad idea to use typedef
to define a pointer to a tagless stucture type.
一般来说,使用typedef定义指向无标记结构类型的指针是个坏主意。
#13
-1
The purpose with typedef is to hide the implementation details, but typedef-ing the pointer property hides too much and makes the code harder to read/understand. So please do not do that.
typedef的目的是隐藏实现细节,但是typedef-ing指针属性隐藏太多,使代码更难读/理解。所以请不要这样做。
If you want to hide implementation details (which often is a good thing to do), do not hide the pointer part. Take for instance at the prototype for the standard FILE
interface:
如果您想隐藏实现细节(这通常是一件好事),不要隐藏指针部分。以标准文件接口的原型为例:
FILE *fopen(const char *filename, const char *mode);
char *fgets(char *s, int size, FILE *stream);
here fopen returns a pointer to some structure FILE
(which you do not know the implementation details for). Maybe FILE
is not such a good example because in this case it could have worked with some pFILE type that hid the fact that it is a pointer.
这里fopen返回指向某个结构文件的指针(您不知道实现细节)。也许FILE不是一个很好的例子,因为在这种情况下,它可以使用某种pFILE类型来隐藏它是一个指针的事实。
pFILE fopen(const char *filename, const char *mode);
char *fgets(char *s, int size, pFILE stream);
However, that would only work because you never mess around with the content that is pointed to directly. The moment you typedef some pointer that you some places modify the code becomes very hard to read in my experience.
然而,这只会起作用,因为您永远不会对直接指向的内容造成混乱。在我的经验中,当您键入某个指针,表示您在某些地方修改了代码时,就会变得非常难以阅读。