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