C++ 中 object->function() 和 object.function() 之间的区别
谁能解释一下这样做之间的区别:
a->height();
和
a.height();
实际上有区别吗?
Can anyone explain the different between doing something like:
a->height();
and
a.height();
Is there actually a difference?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
在第一个示例中,a 是指向对象的指针,在第二个示例中,它是对象本身(或对象的引用)。在最低级别上,两者之间没有明显区别。
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.
这是一个奇怪的问题,假设我们正在讨论内置的
->
。听起来有点像“锤子和苹果有什么区别”。通常,当两种变体至少在某种程度上可以互换且同时适用时,就会出现有关“差异”的问题。因此,人们会询问“差异”来决定使用哪种变体。这里的情况并非如此。您不能让
a->height()
和a.height()
同时有效。两者中只有一个有效,具体取决于a
的类型。也就是说,您无法选择使用哪个版本。如果左侧是指向对象的指针,则第一个(带有->
)适用。第二个(只有.
)仅适用于左侧是对象值本身的情况。所以,这就是全部。->
只是一元*
和.
组合的简写,意味着当a
为指针a->height()
相当于(*a).height()
。因此,一个更合理的问题是关于a->height()
和(*a).height()
之间的区别。答案是:没有区别(同样,只要我们考虑内置的->
)This is a strange question, assuming that we are talking about the built-in
->
. It sounds a bit like "what's the difference between a hammer and an apple". Usually a question about the "difference" applies when the two variants are at least somewhat interchangeable, both applicable at the same time. So, people would ask about the "difference" to decide, which variant to use. This is not the case here.You can't have both
a->height()
anda.height()
valid at the same time. Only one of the two can be valid, depending on the type ofa
. I.e. you don't have a choice of which version to use. The first one (with a->
) is applicable if the left-hand side is a pointer to an object. The second one (with just a.
) is only applicable when you the left-hand side is the object value itself. So, that's all there's to it.The
->
is just a shorthand for a combination of unary*
and.
, meaning that whena
is a pointera->height()
is equivalent to(*a).height()
. So, a more reasonable question would be about the difference betweena->height()
and(*a).height()
. And the answer is: there's no difference (again, as long as we are considering the built-in->
)它基本上归结为你如何声明“a”。如果你这样做:
那么“a”本身就是一个对象,并且你使用“.”。参考其成员。
如果你这样做:
那么“a”是一个指向对象的指针,而不是它本身是一个对象。然后你使用“->”符号。
(上述规则存在一些潜在的例外情况,但大多数人都不会遇到。)
It basically boils down to how you declared "a". If you do:
then "a" is itself an object, and you use "." to reference its members.
If you do:
then "a" is a POINTER TO an object, not itself an object. Then you use the "->" notation.
(There are some potential exceptions to the above rules, but they're not something most people ever encounter.)
还值得一提的是,某些对象(例如智能指针)支持两种表示法。在这种情况下,第一个将引用指针指向的对象,第二个将引用智能指针本身。
It's also worth mentioning that some objects like smart pointers support both notations. In that case, the first would refer to the object pointed to by the pointer- the second would refer to the smart pointer itself.
operator->
后跟函数调用,将导致返回的指针被取消引用,并在结果对象上调用函数。简而言之,a->foo()
是(*a).foo()
的简写。除了
a->foo()
要求a
是指向定义foo
的类的指针这一正确答案之外,一个人为的示例可能是告诉一些不同的事情:在智能指针和 stl 迭代器的上下文中,您经常会看到这些类型的
operator->
定义。在这种情况下,该定义确实遵循 Stroustrup 的准则,即不要将其滥用于违反直觉的内容,例如我的示例,而是使定义类可用,就好像它“指向”某个对象一样。The
operator->
, followed by a function call, will result in the returned pointer being dereferences, and the function being called on the resulting object. In short,a->foo()
is shorthand for(*a).foo()
.Apart from the correct answer that
a->foo()
requiresa
to be a pointer to a class definingfoo
, a contrived example may tell something different:In the context of smartpointers and the stl iterators, you will often see these kinds of
operator->
definition. In that context, the definition does follow Stroustrup's guideline to not abuse it for something counter-intuitive, like my example, but to make the defining class usable as if it were 'pointing' to some object.假设
a
是指向某个对象的指针,那么:这:
只是简写:
它允许您通过指针而不仅仅是普通对象(或引用)来调用方法。
您实际上不需要使用 ->;版本,但是当您将几个调用链接在一起时,它的用处就显而易见了。
如果你写这么长的话,那就是:
很难将取消引用(
*
)与其取消引用的指针相关联。而第一个版本->左边的东西是一个指针,右边的东西是指针被取消引用后对象的一部分。Assuming that
a
is a pointer to some object then:This:
Is just shorthand for:
It allows you to call a method via a pointer rather than just a plain object (or reference).
You don't actually need to use the -> version but when you chain a couple of calls togther it becomes obvious why it is useful.
If you write this long hand it is:
Its hard to correlate the de-reference (the
*
) to the pointer it is de-referencing. While the first version -> the thing on the left is a pointer the thing on the right the part of the object after the pointer has been de-referenced.正如其他人所说,如果您正在谈论指针的取消引用,那么差异不会非常显着。但更重要的是,如果
a
是实例或引用并且定义了operator->
函数,那么您可能会看到非常不同的行为。a.name()
会调用 a 的name()
函数,而a->name()
可能会调用其他类型的name()
函数以及该类决定执行的任何其他工作(这是一个返回指针的函数调用,因此“邪恶”类只要返回一个有效的指针就可以做它想做的大多数事情)。这主要用于智能指针,但语言中对此没有保证。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 anoperator->
function then you could see very different behaviors.a.name()
would call a'sname()
function whilea->name()
could be calling some other type'sname()
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.这一切都归结为您希望代码本身的可读性以及您希望代码的速度有多快。在汇编程序的最低级别,它归结为堆栈上的推/拉。在当今拥有快速计算机/MCU 的现实生活中,这并不重要。这是您使用的编程风格。两种方法都可以,但不要混合使用。这可能会让其他程序员难以阅读。
It all boils down to how readable you want the code itself and how fast you want it to be. At lowest level in assembler it's comes down to push/pull on stack. In real life today with fast computers/MCU it doesn't matter. It's the style of programming you use. Both ways are fine but don't mix them. That can make it difficult to read for other programmers.