【问题标题】:memory of a reference variable in c++?c++中引用变量的内存?
【发布时间】:2017-05-17 14:29:40
【问题描述】:

我刚开始从基础开始学习 Cpp,当我遇到引用变量时感到很困惑。

据我所知,引用变量就像一个别名(同一内存的另一个名称),所以在这种情况下它需要任何内存。

当我运行以下代码时:

class sample_class
{
    public:
        int num; //line1
        int& refnum = num; //line2
}

int main()
{
    sample_class sample_object;
    cout<< "sample_class object size : " << sizeof(sample_object) <<endl;
    return 0;
}

我得到的输出为:

sample_class 对象大小:8

==>这里,num 的大小是 4 字节(32 位编译器)和 refnum,因为引用只是 num 的别名。那么,为什么在这种情况下,对象的大小是8

==>另外,如果真的 refnum 就像一个别名,那么这个信息(refnum 也持有/别名到 num 的相同内存地址的信息)何时被存储?

已编辑:

并考虑这种情况(更改sample_class 的定义):

class sample_class
{
    public:
        char letter; //line3
        char& refletter = letter; //line4
        char letter_two; //line5
}

在这里,如果我打印sample_class 对象的对象大小,我得到它为12(尽管letterrefletterletter_two 的大小都等于1)。但如果我评论line 4,对象大小只是2这是怎么回事???

我有兴趣从基础开始学习,所以如果我在任何地方有错误,请纠正我

【问题讨论】:

  • int&amp; refnum = i; 中的i 是否意味着num
  • sry...这是一个拼写错误...已编辑...

标签: c++


【解决方案1】:

引用是别名,不应将其视为新变量。您无法获取其地址,也无法获取其大小。任何这样做的尝试都将获得别名对象的地址或大小。在实践中,大多数实现都像指针一样实现它们,但标准并不要求这样做。它没有提及预期大小以供参考。

发件人:http://en.cppreference.com/w/cpp/language/reference

引用不是对象;它们不一定占用存储空间,尽管如果有必要实现所需的语义,编译器可能会分配存储空间(例如,引用类型的非静态数据成员通常会将类的大小增加存储内存地址所需的数量) .

编辑:c++ 标准为实现提供了很大的余地,可以自行决定类型和类的大小,以适应每种架构的独特要求。在这种情况下,在您的班级成员之间引入了填充。 C++ 中没有要求类的大小必须等于其成员大小的总和。有关该主题的更多信息,请参阅 cppreference.com 上的 Objects and alignment

编辑 2:关于sizeof(T&amp;) 似乎仍然存在一些混淆。

来自http://en.cppreference.com/w/cpp/language/sizeof

当应用于引用类型时,结果是被引用类型的大小。

表达式sizeof(T&amp;) 被视为就像您编写了sizeof(T)。这并不意味着T&amp; 的大小等于T 的大小。只是不能直接用sizeof得到引用的大小。

【讨论】:

  • @saikiran 这是一个不同的问题,有不同的答案,但 t 博士的答案解决了最可能的可能性:填充以确保最佳内存对齐。
【解决方案2】:

除了已经提供的答案,我建议阅读有关填充的材料:

Data structure padding

关于 C++ 中的类和结构的填充,这是一个很好的基本讨论,并有一些简单的例子可供考虑。

【讨论】:

  • 我已经浏览了链接@Dr t,但我在这里使用了所有char,那么为什么需要对char 的每个变量进行填充(看看我的新代码 - line3,4,5) 和如果我评论 line4,为什么我将它的对象大小设为 2
  • @saikiran 你有charchar&amp;char。引用的内存布局要求未由标准固定,但它们可能与char 的不同。与包含三个charstruct 的大小进行比较(无参考)。请记住,sizeof(T&amp;) 给出了类型 T 的大小,而不是引用的大小。 sizeof(char&amp;) == 1 不暗示 char&amp; 的大小为 1,只是 char 的大小为 1。
  • @FrançoisAndrieux,我注意到了你所说的。但是,即使char&amp; 占用了1 byte,为什么编译器会填充剩余的字节?在int 的情况下,情况有所不同,但这里为什么还要填充剩余的正常char
  • @FrançoisAndrieux,但在我的情况下,char&amp; 所指的值也是1 byte,因为letter 的大小是1 byte
  • @saikiran 您可能在 x86 平台上,其中引用的大小为 4,对齐要求为 4。由于您的成员按顺序存储,因此您将有 1 个字节用于 @987654344 @,3 个字节的填充(因为引用只能从第 4 个字节开始),refletter 的 4 个字节,然后 letter_two 的 1 个字节。我不确定最后 3 个字节是做什么用的,我猜你的 struct 的对齐要求是 4,它被填充为 4 个字节的倍数。
【解决方案3】:

引用存储它引用的变量的地址(如具有更强前置/后置条件的指针)。 这意味着sizeof(T&amp;) == sizeof(T*) == 4 在 32 位架构上

@FrançoisAndrieux 评论T&amp; 的实际大小:

@nefas 您声明“这意味着 sizeof(T&amp;) == sizeof(T*) == 4 在 32 位架构上。”但是这是错误的。尝试使用更大的T。例如,sizeof(std::array&lt;int, 10&gt;&amp;) 比指针大得多。你的大小是T,而不是T&amp;

在计算类/结构的大小时必须考虑的另一件事是结构/类的填充:结构的大小可能高于其成员大小的总和(我不会解释一下填充是如何工作的,因为我对此没有足够的了解)。

【讨论】:

  • 将引用实现为指针并不是标准强制要求的,它只是一种非常流行的实现选择。
  • 那是在实现层面,而不是在语言层面!
  • 我没有说一个是使用另一个实现的,但我说它们具有相似的语义。
  • 我不知道,那个。我已更新我的答案以考虑您的评论。
猜你喜欢
  • 1970-01-01
  • 2014-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-21
  • 2012-01-14
相关资源
最近更新 更多