C++ typedef 指针是个好主意吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/750178/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 17:05:19  来源:igfitidea点击:

Is it a good idea to typedef pointers?

c++cpointerstypedefconventions

提问by Unknown

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?

这有什么可取之处吗?

回答by Artelius

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 neverdereference 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, if you change to using an ID rather than a pointer (or vice versa) existing code won't break because the pointer was never supposed to be dereferenced in the first place.

这也使得将来在需要时更容易更改 API。例如,如果您改为使用 ID 而不是指针(反之亦然),现有代码不会中断,因为从一开始就不应该取消引用指针。

回答by sigjuice

Not in my experience. Hiding the '*' makes the code hard to read.

不是我的经验。隐藏“ *”会使代码难以阅读。

回答by Jonathan Leffler

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, 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 SigCatchertype above) by writing:

 typedef SigCatcher (*SignalFunction)(int, SigCatcher);

Or, to declare the signal()function:

 extern SigCatcher signal(int, SigCatcher);
删除声明是指向signal()函数的指针的正确类型,而不是信号捕获器的指针。可以SigCatcher通过编写更清楚(使用上面更正的类型):

 typedef SigCatcher (*SignalFunction)(int, SigCatcher);

或者,声明signal()函数:

 extern SigCatcher signal(int, SigCatcher);

That is, a SignalFunctionis a pointer to a function which takes two arguments (an intand a SigCatcher) and returns a SigCatcher. And signal()itself is a function which takes two arguments (an intand a SigCatcher) and returns a SigCatcher.

也就是说, aSignalFunction是一个指向函数的指针,该函数接受两个参数(anint和 a SigCatcher)并返回 a SigCatcher。并且signal()它本身是一个函数,它接受两个参数(anint和 a SigCatcher)并返回 a SigCatcher

回答by Sad Developer

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。但是对于 typedef,这不会发生:

typedef int* pInt;
pInt pointer1, pointer2;

They are both int *now.

他们现在都是int *

回答by cmaster - reinstate monica

My answer is a clear "No".

我的回答是明确的“不”。

Why?

为什么?

Well, first of all, you simply exchange a single character *for another single character p. That is zerogain. 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 myBarto be changed by passing it to foo(). After all, I'm passing by value, so foo()only ever sees a copy of myBarright? Not when SomeTypeis aliased to mean some kind of pointer!

我不希望myBar通过将其传递给 来改变的含义foo()。毕竟,我是通过值传递的,所以foo()只能看到一个副本,myBar对吗?不是 whenSomeType别名表示某种指针!

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.)

(我相信 typedefing 指针类型的习惯只是一种误导,试图隐藏一个程序员拥有多少颗星http://wiki.c2.com/?ThreeStarProgrammer。)

回答by dgnuff

No.

不。

It will make your life miserable the moment you mix it with const

与它混在一起的那一刻,它会让你的生活变得悲惨 const

typedef foo *fooptr;
const fooptr bar1;
const foo *bar2

Are bar1and bar2the same type?

bar1bar2同类型吗?

And yeah, I am just quoting Herb Sutter's Guru. Much truth did she speak. ;)

是的,我只是在引用 Herb Sutter 的 Guru。她说了很多实话。;)

-- Edit --

- 编辑 -

Adding link to cited article.

添加引用文章的链接。

http://www.drdobbs.com/conversationsa-midsummer-nights-madness/184403835

http://www.drdobbs.com/conversationsa-midsummer-nights-madness/184403835

回答by Martin York

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.

回答by JaredPar

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 :)

我个人避免使用 typedef。让用户明确地说他们想要一个 Foo* 比 PFoo 要清楚得多。如今,Typedef 最适合使 STL 可读:)

typedef stl::map<stl::wstring,CAdapt<CComPtr<IFoo>> NameToFooMap;

回答by Chand

Typedef is used to make code more readable, but making pointer as typedef will increase confusion. Better to avoid typedef pointers.

Typedef 用于使代码更具可读性,但将指针设为 typedef 会增加混乱。最好避免使用 typedef 指针。

回答by Jonathan Leffler

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

将 aa 指针 typedef 用于未标记的结构

The question Size of a struct that is defined as a pointerraises an interesting side-light on using typedeffor (structure) pointers.

定义为指针的结构的大小问题引发了关于使用typedeffor(结构)指针的有趣侧面。

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 typedefwithout a tag).

成员的详细信息与本次讨论完全无关;重要的是这不是一个不透明的类型typedef struct tag *tag;(并且你不能通过没有typedef标签的a 定义这样的不透明类型)。

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 sizeof(*Information), for example, and 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.

事实上,如果你想分配这样的结构,除了通过动态分配(或模拟动态分配的代理技术)之外,你不能创建一个。没有办法创建其指针被调用的结构类型的局部变量,也没有办法创建结构类型的Information文件范围(全局或static)变量,也没有办法嵌入这样的结构(如与指向这种结构的指针相反)转换为另一个结构或联合类型。

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 infochanges, 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这一事实之外,这是一个很好的做法——如果类型发生info变化,大小分配将保持准确。但在这种情况下,它也是获取结构大小和分配结构的唯一方法。没有其他方法可以创建结构的实例。

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'd时,必须定义结构的细节。

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 typedefto define a pointer to a tagless stucture type.

通常,使用typedef定义指向无标记结构类型的指针是一个坏主意。