我可以使用什么代替箭头运算符`->`?


112

箭头运算符(->)的同义词是什么?

Answers:


148

以下两个表达式是等效的:

a->b

(*a).b

(正如Konrad所提到的,操作符会过载,但这是不寻常的)。


9
过载问题比您想象的要少得多。不久前,STL实现者没有->某些迭代器类型的重载运算符,因此您必须使用*.。许多库对它们的定义不一致。当您使用模板并且不知道确切的类型时,它会变得非常烦人。
康拉德·鲁道夫

1
您也可以a[0].b代替(*a).b。但是它的结构不那么恰当。
Sellorio

2
男孩,经过多年的C#编程,回到C ++不仅在认知上很费力,而且C ++语法丑陋又令人讨厌。使用后我想洗个澡。用c和c ++编写的程序只会鼓励不好的编程。前Unix的Apple努力使这种语言与Pascal一样漂亮。
ATL_DEV

@ATL_DEV我认为许多丑陋的东西不再被认为是惯用的了,但是不幸的是,这并不意味着您不能以不熟悉C ++程序员的身份来熟悉它。同样,语法上不错的路径通常不是语义上不错的路径,但是这种情况也越来越好了。但话又说回来,我有C ++斯德哥尔摩综合症。
蒂姆·塞吉

@TimSeguine如果您想查看漂亮的代码,请查看Macintosh内部的文档。我认为他们发明了CamelCase。描述性很强的变量名和格式精美的代码。他们设法使后来的C代码几乎与先前的Pascal代码一样华丽。
ATL_DEV

70

a->b通常是的同义词(*a).b。由于运算符的绑定强度,此处的括号是必需的,*并且.::绑定更牢固且首先执行,因此: *a.b无效.。因此,这等效于*(a.b)

但是,请提防​​重载:由于->*都可以重载,因此它们的含义可能会大不相同。


1
通过binding strength你的意思是运算符优先级?如果不是,两者之间有什么区别?
vishnuprasanth

1
@Vizkrig是的,这两个术语可以互换使用(尽管“操作员优先”似乎至少在最近几年更为频繁)。
康拉德·鲁道夫

45

C ++语言将箭头运算符(->)定义为取消引用指针的同义词,然后.在该地址上使用-operator。

例如:

如果有一个对象anObject和一个指针,则aPointer

SomeClass anObject = new SomeClass();
SomeClass *aPointer = &anObject;

为了能够使用对象方法之一,您可以取消引用指针并对该地址进行方法调用:

(*aPointer).method();

可以使用箭头运算符编写:

aPointer->method();

存在箭头运算符的主要原因是,它缩短了非常常见的任务的键入时间,并且还很容易忘记指针取消引用前后的括号。如果您忘记了括号,则.-operator的绑定会更牢固,然后* -operator会使我们的示例执行为:

*(aPointer.method()); // Not our intention!

其他一些答案也提到了C ++运算符可以重载并且它不是那么常见。


8
new SomeClass()返回一个指针(SomeClass *),而不是SomeClass对象。从声明开始,anObject然后aPointer再使用p
musiphil

总体而言,这种解释在理论上非常贴切,只是对象的变化使它有些混乱。但是这个过程是更好地描述
代码人

17

在C ++ 0x中,运算符具有第二个含义,表示函数或lambda表达式的返回类型

auto f() -> int; // "->" means "returns ..."

1
从技术上讲,它不再是那里的“运营商”,或者是?
马丁·巴

6
@Martin大多数人将“运算符”一词用于许多未直接用于计算值的事情。就像“ ::”(“作用域运算符”)一样。确切地说,我不知道该标准的观点是什么。从抽象的意义上讲,可以将“->”视为将一系列类型(参数)映射到返回类型的函数运算符,就像haskell运算符一样,该运算符也写为“->”。
Johannes Schaub-litb 2010年

6
我投降!:-P
Martin Ba

2
@ JohannesSchaub-litb:::实际上是一个运算符,例如.->,在标准中称为“范围分辨率运算符”。
musiphil

13

我通常从右到左阅读它,并称之为“ in”

foo->bar->baz = qux->croak

变成:

“ foo中bar的baaz在qux中变得嘶哑”。


1

-> 在访问您有指针的数据时使用。

例如,您可以创建一个指针ptr来指向类型为int intVar的变量,如下所示:

int* prt = &intVar;

然后,仅可以通过取消引用该指针,在其上使用一个函数(例如foo),以在指针指向的变量上调用该函数,而不是在该变量的内存位置的数值上调用该函数:

(*ptr).foo();

如果没有括号,编译器将理解为*(ptr.foo())由于运算符优先级,这不是我们想要的。

这实际上与键入相同

ptr->foo();

由于->取消了对该指针的引用,因此调用foo()了指针指向我们的变量上的函数。

类似地,我们可以->用来访问或设置类的成员:

myClass* ptr = &myClassMember;
ptr->myClassVar = 2; 

0

您可以使用->定义功能。

auto fun() -> int
{
return 100;
}

这不是lambda。这确实是一个功能。“->”表示函数的返回类型。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.