问题描述
看起来,引用只是一个别名,但是,例如,向 struct
添加引用字段会增加结构的大小,即使在声明时初始化引用作为相同结构的另一个字段的别名。
例如:
#include <iostream>
using namespace std;
int
main(int,char **)
{
struct {
int integers[2];
} first;
struct {
int integers[2];
int &one = integers[0];
int &two = integers[1];
} second;
cout << sizeof first << " " << sizeof first.integers << " " <<
sizeof second << " " << endl;
return 0;
};
上面的程序在此处打印:8 8 24
。我理解的前两个数字,第三个——不。为什么添加这样的引用很重要——内存中存储了什么,在编译时无法解析?与指针不同,一旦声明,引用无论如何都不能按设计更改,对吗?那么为什么要存储它们?
解决方法
这个答案提到对象很可能会被优化掉,但是调用 sizeof
可以强制它们不被优化,因为删除它们将是结构大小的“可观察”变化:>
https://stackoverflow.com/a/55060982
,即使按照您的方式定义了 first
和 second
结构,我认为,这些引用成员也无法优化掉(如果我们不是在谈论您编写的特定程序,而是在使用这些结构的一般情况)。例如,假设在代码中的某个时刻,您将决定创建 second
结构的实例,但以不同的方式初始化引用成员,甚至可能以动态方式,在编译时未知。考虑以下用法:
#include <iostream>
int main()
{
struct
{
int integers[2];
} first;
struct
{
int integers[2];
int &one = integers[0];
int &two = integers[1];
} second;
int user_choice{ 0 };
std::cin >> user_choice;
int i{ 56 },j{ 78 };
decltype(second) third{ {12,34},i,(user_choice < 42) ? i : j };
std::cout << third.integers[0] << ' ' << third.integers[1] << ' '
<< third.one << ' ' << third.two << '\n';
}
在上面的程序中,编译器根本无法事先知道,third.two
将引用 i
还是 j
:这取决于用户在运行时输入的数字(例如,通过输入 7
而不是 100
在 https://godbolt.org/z/43bM1o 尝试)。