具有
struct Person {
string name;
};
Person* p = ...
假设没有运算符过载。
哪个更有效(如果有的话)?
(*p).name
vs。 p->name
在我脑后的某个地方,我听到一些铃声响起,*
取消引用操作员可能会创建一个对象的临时副本;这是真的吗?
这个问题的背景是这样的情况:
Person& Person::someFunction(){
...
return *this;
}
我开始怀疑,如果将结果更改为Person*
而最后一行只是return this
会有什么不同(性能)?
答案 0 :(得分:9)
没有区别。即使标准说这两个是等价的,如果那里有任何编译器都没有为这两个版本生成相同的二进制文件,那就太糟糕了。
答案 1 :(得分:8)
当您返回引用时,这与传回指针完全相同,指针语义被排除。
您传回了sizeof(void*)
元素,而不是sizeof(yourClass)
。
所以当你这样做时:
Person& Person::someFunction(){
...
return *this;
}
您返回一个引用,该引用具有与指针相同的内在大小,因此没有运行时差异。
答案 2 :(得分:2)
是的,阅读和打字要困难得多,所以使用x->y
而不是(*x).y
要好得多 - 但除了输入效率之外,绝对没有区别。编译器仍然需要读取x
的值,然后将偏移量添加到y
,无论是使用一种形式还是另一种形式[假设没有涉及的有趣对象/类覆盖{{1}当然,分别为{}和operator->
引用operator*
时肯定没有创建额外的对象。指针的值被加载到处理器[1]中的寄存器中。就是这样。
返回引用通常更有效,因为它将指针(伪装)返回给对象,而不是制作对象的副本。对于大于指针大小的对象,这通常是一个胜利。
[1]是的,我们可以为没有寄存器的处理器配备C ++编译器。我知道Rank-Xerox中至少有一个处理器是我在1984年左右看到的,它没有寄存器,它是一个专用的LiSP处理器,它只有一个LiSP对象的堆栈......但它们远非常见在现今世界里。如果某人在没有注册表的处理器上工作,请不要仅仅因为我没有涵盖该选项而拒绝我的回答。我试图让答案变得简单。
答案 3 :(得分:1)
任何好的编译器都会产生相同的结果。您可以自己回答这个问题,将两个代码编译成汇编程序并检查生成的代码。