任何人都可以解释这样做的不同之处:
a->height();
和
a.height();
实际上有区别吗?
答案 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并不重要。这是你使用的编程风格。两种方式都很好,但不要混合它们。这可能使其他程序员难以阅读。