【问题标题】:What can I use instead of the arrow operator, `->`?我可以使用什么来代替箭头运算符`->`?
【发布时间】:2010-09-18 07:01:12
【问题描述】:

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

【问题讨论】:

    标签: c++ pointers


    【解决方案1】:

    你可以使用->来定义一个函数。

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

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

    【讨论】:

      【解决方案2】:

      -> 用于访问您有指针指向的数据。

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

      int* prt = &intVar;
      

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

      (*ptr).foo();
      

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

      这其实和打字是一样的

      ptr->foo();
      

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

      同样,我们可以使用-> 来访问或设置一个类的成员:

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

      【讨论】:

        【解决方案3】:

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

        例如:

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

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

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

        (*aPointer).method();
        

        可以用箭头操作符来写:

        aPointer->method();
        

        箭头操作符存在的主要原因是它缩短了一个非常常见的任务的打字时间,而且它也很容易忘记指针解引用周围的括号。如果你忘记了括号,.-operator 将绑定比 *-operator 更强,并使我们的示例执行为:

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

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

        【讨论】:

        • new SomeClass() 返回一个指针 (SomeClass *),而不是 SomeClass 对象。你从声明anObjectaPointer 开始,但之后你使用p
        • 总的来说这个解释理论上很贴切,只是对象的变化有点绕。但这个过程更好地描述
        【解决方案4】:

        我主要是从右到左阅读它并称之为“in”

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

        变成:

        “foo 中 bar 中的 baz 变成 qux 中的 croak。”

        【讨论】:

          【解决方案5】:

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

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

          【讨论】:

          • 从技术上讲,它不再是那里的“操作员”,或者是吗?
          • @Martin 大多数人将“运算符”一词用于许多不直接用于计算值的事物。就像“::”(“范围运算符”)一样。我不知道标准的观点是什么,确切地说。在抽象意义上,可以将“->”视为将一系列类型(参数)映射到返回类型的函数运算符,就像 haskell 运算符一样,它也写为“->”。
          • @JohannesSchaub-litb:::实际上是一个运算符,就像.->一样,在标准中被称为“范围解析运算符”。
          【解决方案6】:

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

          a->b
          
          (*a).b
          

          (如 Konrad 提到的,受运算符重载的影响,但这是不寻常的)。

          【讨论】:

          • 重载问题比您想象的要少得多。不久前,STL 实现者对某些迭代器类型没有重载的-> 运算符,因此您不得不 使用*.。许多库对它们的定义不一致。当您使用模板并且不知道确切的类型时会变得非常烦人。
          • 你也可以用a[0].b代替(*a).b。但它的结构不会那么正确。
          • 男孩,经过多年的 c# 编程,回到 c++ 不仅在认知上很费力,c++ 语法也很丑陋和令人讨厌。用完之后就想冲个澡。用 c 和 c++ 编写的程序只会鼓励糟糕的编程。 Apple,pre-unix,努力使语言像 Pascal 一样漂亮。
          • @ATL_DEV 我认为很多丑陋的东西不再被认为是惯用的,但不幸的是,这并不意味着作为一名练习 C++ 程序员的你可以负担得起不熟悉它的代价。此外,语法上好的路径通常不是语义上的好路径,但它也在变得更好而不是更糟。但话又说回来,我有 C++ 斯德哥尔摩综合症。
          • @TimSeguine 如果您想查看漂亮的代码,请查看 Macintosh 内部的文档。我认为他们发明了 CamelCase。非常具有描述性的变量名称和格式优雅​​的代码。他们设法使后来的 C 代码几乎和早期的 Pascal 代码一样华丽。
          【解决方案7】:

          a->b 通常是(*a).b 的同义词。由于运算符*. 的绑定强度,此处的括号是必要的:*a.b 不起作用,因为. 绑定更强并且首先执行。因此这相当于*(a.b)

          但请注意重载:由于 ->* 都可以重载,因此它们的含义可能会有很大的不同。

          【讨论】:

          • binding strength 你的意思是运算符优先级?如果不是,两者有什么区别?
          • @Vizkrig 是的,这两个术语可以互换使用(尽管“运算符优先级”似乎更频繁,至少在最近几年)。
          猜你喜欢
          • 1970-01-01
          • 2018-08-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-09-11
          • 2013-02-15
          • 1970-01-01
          相关资源
          最近更新 更多