11

struct Person {
   string name;
};

Person* p = ...

假设没有运算符被重载。


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

(*p).name 对比 p->name

在我脑后的某个地方,我听到一些铃声响起,*解引用运算符可能会创建对象的临时副本;这是真的?


这个问题的背景是这样的情况:

Person& Person::someFunction(){
    ...
    return *this;
}

我开始怀疑,如果将结果更改为Person*和最后一行简单地return this会产生任何影响(在性能方面)?

4

4 回答 4

9

没有区别。甚至标准也说这两者是等价的,如果有任何编译器不会为两个版本生成相同的二进制文件,那就太糟糕了。

于 2013-05-03T09:21:19.840 回答
8

当你返回一个引用时,这与传回一个指针完全相同,指针语义被排除在外
你传回一个sizeof(void*)元素,而不是一个sizeof(yourClass).

所以当你这样做时:

Person& Person::someFunction(){
    ...
    return *this;
}

您返回一个引用,并且该引用具有与指针相同的内在大小,因此没有运行时差异。

您对 的使用也是(*i).name如此,但在这种情况下,您会创建一个l-value,它与引用具有相同的语义(另请参见此处

于 2013-05-03T09:26:22.777 回答
2

是的,阅读和打字要困难得多,所以你最好使用x->ythan (*x).y- 但除了打字效率之外,绝对没有区别。编译器仍然需要读取 的值,x然后将偏移量添加到y,无论您使用一种形式还是另一种形式[当然,假设没有涉及分别覆盖operator->and的有趣对象/类operator*]

引用时肯定不会创建额外的对象(*x)。指针的值被加载到处理器 [1] 中的寄存器中。而已。

返回引用通常更有效,因为它返回指向对象的指针(变相),而不是制作对象的副本。对于大于指针大小的对象,这通常是一个胜利。

[1] 是的,我们可以为没有寄存器的处理器提供 C++ 编译器。我知道我在 1984 年左右看到的 Rank-Xerox 的至少一个处理器,它没有寄存器,它是一个专用的 LiSP 处理器,它只有一个用于 LiSP 对象的堆栈......但它们远非常见在现今世界里。如果有人在没有寄存器的处理器上工作,请不要仅仅因为我没有涵盖该选项而否决我的答案。我试图保持答案简单。

于 2013-05-03T09:35:30.057 回答
1

Any good compiler will produce the same results. You can answer this yourself, compile both codes to assembler and check the produced code.

于 2013-05-03T09:22:51.757 回答