返回对成员变量数据的引用的开销

Posted

技术标签:

【中文标题】返回对成员变量数据的引用的开销【英文标题】:Overhead of returning reference to member variable data 【发布时间】:2018-12-28 21:59:45 【问题描述】:

我是 C++ 新手,当类方法返回对作为原始数据的成员变量的引用(而不是指针或引用)时,我对幕后发生的事情感到困惑。这是一个例子:

#include <iostream>

using namespace std;

struct Dog 
    int age;
;

class Wrapper 
public:
    Dog myDog;

    Dog& operator*()  return myDog; 
    Dog* operator->()  return &myDog; 
;

int main() 
    auto w = Wrapper();

    // Method 1
    w.myDog.age = 1;
    cout << w.myDog.age << "\n";

    // Method 2
    (*w).age = 2;
    cout << w.myDog.age << "\n";

    // Method 3
    w->age = 3;
    cout << w.myDog.age << "\n";

我的问题是:当代码读取 (*w)w-&gt;(如在 main 函数中)时,运行时会发生什么?每次看到(*it)it-&gt; 时,它是否计算myDog 字段的地址?与直接访问myDog_ 相比,这两种访问方法是否存在开销?

谢谢!

【问题讨论】:

您的帖子中有大量代码用于解决一个非常具体的问题。请确保发布minimal reproducible example,并强调minimal。另外,您为什么担心编译器看到某些内容时的行为?除非您询问编译时间,否则这似乎与任何事情都无关。无论如何,编译器并没有真正看到地址。它们直到运行时才可用,此时编译器早已不复存在。 所有方法都是等价的。在汇编级别,引用只是一个指针。 澄清一下,是否保证指针位置是在编译时而不是在运行时计算的?因为对operator-&gt;() 代码的一种解释是myDog 的地址是在运行时计算的,对吧? @xaxxon 感谢您的反馈。我用较短的代码示例替换了代码示例,并澄清了问题。我问的是运行时性能。 【参考方案1】:

从技术上讲,您所要求的完全是系统/编译器特定的。实际上,指针和引用在实现上是相同的。

没有理性的编译器会处理

(*x).y

x->y 

不同。在幕后,两者通常都出现在汇编语言中,类似于

y(Rn)

其中 Rn 是保存 x 地址的寄存器,y 是 y 在结构中的偏移量。

问题在于 C++ 是建立在 C 之上的,而 C 又是有史以来设计最多的 f*&*) *p 编程语言。引用构造是对 C 传递参数的无能方法的一种解决方法。

【讨论】:

以上是关于返回对成员变量数据的引用的开销的主要内容,如果未能解决你的问题,请参考以下文章

传递参考的开销是多少?

移动语义+对成员成员变量的引用 - 解决方案和命名法?

Java内存成员变量局部变量

Java内存成员变量局部变量

是否有对成员变量的任何引用? [关闭]

通过添加 0 修复对静态成员变量的未定义引用