2012-07-16 100 views
4

的帖子What can I use instead of the arrow operator, `->`?Arrow operator (->) usage in C 状态C++箭头操作符equivelence

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

x->y 
(*x).y 

但当当作这似乎并不总是真的数学等价。

为什么用

a->(*b).c 

更换

a->b->c 

何时G ++抛出一个错误?

看来上面的等值不是总是可以替换。因此,我认为“等值”一词有点误导。

此外,我不是指在这个问题上的任何重载。

+0

顺便说一下,在这方面你错了(见答案),但一般来说'a-> b'和'(* a).b'不一定等价,因为' - >'和'*'可以为你自己的类重载。当'a'是指针类型时,它们* *完全等价,但是(或者当'operator - >'和'operator *'正确超载时)。 – 2012-07-16 19:34:56

+0

Konrad,我的观点是我们必须小心“完全等效”这个词。当我读到这个短语时,它会显示“第一个的任何实例可以被第二个替换”。看来在这种情况下,等价取决于操作的顺序。 – Tommy 2012-07-16 19:49:43

+0

他们*完全等同。但在进行替换时,您仍然需要遵守优先规则。你不能只做文本替换。毕竟,在数学中,“x + x”和“2 * x”是完全等价的(它们对x的所有值都是相等的),但是当你忽略数学规则并用数学表达式“ x + x/2“会得到错误的结果(因为x + x/2≠2 * x/2)。 – 2012-07-16 20:02:03

回答

16

你的关联性规则错了。 a->b->c(a->b)->c,而不是a->(b->c),所以它变成(*(a->b)).c(然后(*((*a).b)).c)。

8

因为您没有正确地更换操作员。它应该是:

(*(a->b)).c 

你治疗你的表达a->(b->c)时,你应该把它当作(a->b)->c

2

你做不正确的更换。

a->b->c相当于(*(a->b)).c

a->(*b).c由于多种原因没有意义。 b不是可以解引用的指针(指针是a->b)。此外,即使它是,在a的字段上下文中使用解除引用的指针也是没有意义的。

1

你所看到的问题是与不同运营商的precendence的问题,您应该使用:(*(x->y)).z(到第二->的操作数是(x->y)z)。但之前已经回答了这个问题。

然而,重要的是要注意,只有指针的等价性才是正确的,并且两个运算符在重载时的属性完全不同。 operator->在语言中具有非常奇怪的语义,因为它不代表单个操作,但可以代表operator->的多个应用程序,直到重载操作符生成一个原始指针,此时它将执行一个等效的最后一个应用程序解除引用和访问权限(即仅针对最后一个应用程序,a->b相当于(*a)->b。)