(*i).member的效率是否低于i->member的效率



具有

struct Person {
   string name;
};
Person* p = ...

假设没有运算符过载。


哪个更有效(如果有的话(?

(*p).namep->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对象的堆栈。。。但在当今世界,它们并不常见。如果有人在一个没有寄存器的处理器上工作,请不要因为我不包括这个选项而否决我的答案。我尽量使答案简单。

任何优秀的编译器都会产生相同的结果。您可以自己回答这个问题,将这两个代码编译到汇编程序并检查生成的代码。

相关内容

  • 没有找到相关文章

最新更新