3

任何人都可以解释做类似的事情之间的区别:

a->height();

a.height();

真的有区别吗?

4

8 回答 8

6

In the first example a is a pointer to an object, in the second example it is the object itself (or a reference to the object). At the lowest level, there is no clear difference between the two.

于 2011-06-05T19:42:53.273 回答
5

这是一个奇怪的问题,假设我们谈论的是内置的->. 这听起来有点像“锤子和苹果有什么区别”。通常,当两个变体至少在某种程度上可以互换,两者同时适用时,就会出现关于“差异”的问题。因此,人们会询问“差异”来决定使用哪个变体。这不是这里的情况。

您不能同时拥有两者a->height()a.height()有效。两者中只有一个是有效的,具体取决于a. 即,您无法选择使用哪个版本。->如果左侧是指向对象的指针,则第一个(带有 a )适用。第二个(只有 a .)仅适用于左侧是对象值本身的情况。所以,这就是它的全部。

The->只是一元*and组合的简写.,这意味着 whena是一个指针a->height()等价于(*a).height()a->height()因此,一个更合理的问题是关于和之间的区别(*a).height()。答案是:没有区别(同样,只要我们考虑内置的->

于 2011-06-05T19:59:18.123 回答
2

它基本上归结为您如何声明“a”。如果你这样做:

SomeClass a;

那么“a”本身就是一个对象,而你使用“.” 引用其成员。

如果你这样做:

SomeClass * a;
a = [some expression that produces a pointer to a SomeClass object];

那么“a”是指向对象的指针,而不是对象本身。然后使用“->”符号。

(上述规则有一些潜在的例外,但它们不是大多数人遇到的。)

于 2011-06-05T19:51:26.250 回答
2

还值得一提的是,像智能指针这样的一些对象同时支持这两种表示法。在这种情况下,第一个将引用指针指向的对象-第二个将引用智能指针本身。

于 2011-06-05T20:02:19.917 回答
2

假设这a是一个指向某个对象的指针,那么:

这个:

a->height();

只是以下的简写:

(*a).height();

它允许您通过指针调用方法,而不仅仅是普通对象(或引用)。
您实际上不需要使用 -> 版本,但是当您将几个调用链接在一起时,它为什么有用就很明显了。

person->body()->arm(right)->hand()->finger(index)->ring()->activate();

如果你写这个长手,它是:

(*(*(*(*(*(*person).body()).arm(right)).hand()).finger(index)).ring()).activate();

很难将取消引用 (the *) 与它正在取消引用的指针相关联。虽然第一个版本 -> 左边的东西是一个指针,右边的东西是指针被取消引用后的对象部分。

于 2011-06-05T20:17:08.670 回答
2

operator->后跟函数调用,将导致返回的指针被取消引用,并在结果对象上调用函数。简而言之,a->foo()是 的简写(*a).foo()

除了a->foo()需要a指向类定义的指针的正确答案之外foo,一个人为的例子可能会说明一些不同的东西:

struct xC {
   struct Member {
      void foo(){printf("xC::Member::foo\n");};
   };
   Member a;
   Member* operator->() { return &a; }
   // following function doesn't really make sense.
   void foo() { printf("xC::foo\n");};
};

int main(){
    xC x;
    x.foo(); // prints "xC::foo".  
    x->foo();// prints "xC::Member::foo"
}

在智能指针和 stl 迭代器的上下文中,您经常会看到这些类型的operator->定义。在这种情况下,定义确实遵循 Stroustrup 的指导方针,不要滥用它来做一些违反直觉的事情,比如我的例子,而是让定义类像“指向”某个对象一样可用。

于 2011-06-05T20:19:35.730 回答
0

As others have said, if you are talking about the dereferencing of a pointer, then the difference would not be terribly significant. More importantly however, if a is a instance or a reference and has defined an operator-> function then you could see very different behaviors. a.name() would call a's name() function while a->name() could be calling some other type's name() function along with any other work the class has decided to do (it is a function call returning a pointer so 'evil' class could do most anything it wants so long as it returns a valid pointer). This is primarily used for smart pointers, but there is no guarantee of that in the language.

于 2011-06-05T20:30:10.120 回答
-2

这一切都归结为您希望代码本身的可读性以及您希望它有多快。在汇编程序的最低级别,它归结为推/拉堆栈。在当今使用快速计算机/MCU 的现实生活中,这并不重要。这是您使用的编程风格。两种方式都可以,但不要混合使用。这会使其他程序员难以阅读。

于 2013-06-11T08:17:10.190 回答