C ++中object-> function()和object.function()之间的区别

时间:2011-06-05 19:40:56

标签: c++ object member dereference

任何人都可以解释这样做的不同之处:

a->height();

a.height();

实际上有区别吗?

8 个答案:

答案 0 :(得分:6)

在第一个示例中,a是指向对象的指针,在第二个示例中,它是对象本身(或对象的引用)。在最低级别,两者之间没有明显的区别。

答案 1 :(得分:5)

这是一个奇怪的问题,假设我们正在讨论内置的->。听起来有点像"锤子和苹果之间的区别"。通常是关于"差异的问题"当两个变体至少在某种程度上可以互换时适用,两者同时适用。所以,人们会问及差异"决定使用哪种变体。这不是这种情况。

您不能同时使a->height()a.height()同时生效。根据{{​​1}}的类型,两者中只有一个可以有效。即您无法选择使用哪个版本。如果左侧是指向对象的指针,则第一个(带有a)适用。第二个(只有一个->)仅适用于左侧是对象值本身的情况。所以,那就是它的全部内容。

.只是一元->*组合的简写,这意味着当.为指针时a相当于{ {1}}。因此,更合理的问题是a->height()(*a).height()之间的区别。答案是:没有区别(只要我们考虑内置的a->height()

答案 2 :(得分:2)

它基本上归结为你如何宣称“a”。如果你这样做:

SomeClass a;

然后“a”本身就是一个对象,你使用“。”引用其成员。

如果你这样做:

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

然后“a”是对象的指针,而不是对象。然后你使用“ - >”符号

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

答案 3 :(得分:2)

还值得一提的是,智能指针等一些对象支持两种符号。在这种情况下,第一个将引用指针指向的对象 - 第二个将引用智能指针本身。

答案 4 :(得分:2)

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

此:

a->height();

只是简写:

(*a).height();

它允许您通过指针而不仅仅是普通对象(或引用)来调用方法 您实际上不需要使用 - >版本,但当你把几个电话串起来时,很明显为什么它有用。

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

如果你写这篇文章,那就是:

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

很难将去引用(*)与它所引用的指针相关联。而第一个版本 - >左边的东西是指针被取消引用后指向对象部分右边的东西。

答案 5 :(得分: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"
}

在smartpointers和stl迭代器的上下文中,您经常会看到这些operator->定义。在这种情况下,该定义确实遵循Stroustrup的指导原则,不要滥用它来反对某些反直觉的东西,比如我的例子,但是要使定义类可用,就像它“指向”某个对象一样。

答案 6 :(得分:0)

正如其他人所说,如果你在谈论指针的解除引用,那么差异就不会非常显着。但更重要的是,如果a是实例或引用,并且定义了operator->函数,那么您可以看到非常不同的行为。 a.name()会调用name()函数,而a->name()可以调用其他类型的name()函数以及该类决定执行的任何其他工作(这是函数调用返回一个指针,所以'邪恶'类可以做任何它想要的东西,只要它返回一个有效的指针)。这主要用于智能指针,但在语言中无法保证。

答案 7 :(得分:-2)

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