我正在学习如何重载" - >"并且文档说:"operator->在它返回的值上再次被调用,直到到达operator->返回一个普通指针.之后,内置语义被应用于那个指针."
虽然很清楚文档说的是什么,但实质上是一个类的重载" - >"可以使用一个"特殊指针",它本身有一个重载的" - >",它可以给出一个"特殊指针"等等直到"平原"指针"找到了,我找不到真正使用它的例子(除非它用于查找链表最后一个元素).
有人可以解释一下幕后的内容是什么(因为这种可能性没有提供"普通指针" - 所以我没有看到任何理由为它提供"特殊指针").
现实世界使用的一个例子也可能有所帮助,因为我可能错过了应用该行为的模型.
另一方面可能需要避免这种行为,怎么可能呢?
那么,->运营商在特殊情况下工作.
可以称之为伪二元运算符.根据它的自然语法,pointer->member它需要两个操作数:左侧的正常运行时操作数和右侧的相当"奇怪"的成员名称操作数.第二个操作数的"奇怪性"源于C++语言没有用户可访问的概念来表示这些操作数.语言中没有任何内容可以将成员名称表示为操作数.没有办法通过代码将成员名称"传递"给用户定义的实现.成员名称是一个编译时实体,在这方面远程类似于常量表达式,但C++中没有常量表达式可以指定成员.(指向成员的指针有表达式,但成员指针却没有).
这在指定重载->运算符的行为时会产生相当明显的困难:我们如何将在右侧指定的内容->(即成员名称)连接到用户编写的代码?不可能直接这样做.摆脱这种情况的唯一方法是间接地执行此操作:强制用户将重载->运算符的用户定义功能引导到某些现有内置运算符的功能中.内置运算符可以通过其核心语言功能自然地处理成员名称.
在这种特殊情况下,我们只有两个候选者将重载的功能引导->到:内置->和内置..->为这个角色选择内置是合乎逻辑的.这产生了一个有趣的副作用:编写重载->运算符的"链式"(递归)序列(由编译器隐式解包)甚至无限递归序列(形成不良)的可能性.
非正式地说,每次使用智能指针时,都会对重载->运算符的这些"递归"属性进行实际使用.如果你有一个指向sptr带有成员的类对象的智能指针member,那么成员访问语法仍然是完全自然的,例如sptr->member.由于重载的隐式"递归"属性,您不必像sptr->->member或sptr->.member具体那样执行此操作->.
请注意,仅当您使用运算符语法调用重载->运算符(即object->member语法)时,才会应用此递归行为.但是,您也可以使用常规成员函数调用语法来调用您的重载->,例如object.operator ->().在这种情况下,调用作为普通函数调用执行,并且不进行递归应用->.这是避免递归行为的唯一方法.如果实现了重载->运算符,其返回类型不支持->运算符的其他应用程序(例如,您可以定义->返回的重载int),那么这object.operator ->()将是调用重载实现的唯一方法.任何使用object->member语法的尝试都将是错误的.