C++ 参考—;sizeof是否返回实际内存大小?
我知道这个问题可能有很多不同的提问方式,但我补充我自己的问题,因为这对我来说还不清楚 考虑以下代码:C++ 参考—;sizeof是否返回实际内存大小?,c++,reference,sizeof,C++,Reference,Sizeof,我知道这个问题可能有很多不同的提问方式,但我补充我自己的问题,因为这对我来说还不清楚 考虑以下代码: long double q = 1.2; long double &p = q; cout << sizeof(p) << endl;` 长双q=1.2; 长双&p=q; 比较和对比: struct container { long double& dbl; }; std::cout << sizeof(container::dbl)
long double q = 1.2;
long double &p = q;
cout << sizeof(p) << endl;`
长双q=1.2;
长双&p=q;
比较和对比:
struct container {
long double& dbl;
};
std::cout << sizeof(container::dbl) << '\n';
std::cout << sizeof(container) << '\n';
那么,在其范围内使用dbl
就是一个左值,也就是说一个引用。这是为dbl
赋值所必需的。因此,dbl
(例如,decltype(dbl)
)的类型是长双精度&
,而不是长双精度
如果sizeof(dbl)
返回引用本身的大小而不是被引用对象的大小,那将是荒谬的
一旦你将引用放入一个结构中,你就有了一个完全不同的beast。作为对象的一部分,引用占用空间,除非包含它的整个对象可以优化掉,否则无法优化掉空间。如果您怀疑是否可以依赖以下类型的sizeof
:
struct A
{
int& r;
};
然后是-您可以依赖包含引用的结构中的sizeof
例如,此代码是安全的:
char* buffer = new char[sizeof(A)];
int value;
A* valueRef = new (buffer) A{value};
缓冲区中有足够的字节来存储对象
struct S {
long double& d;
};
static_assert(sizeof(S::d) == sizeof(long double));
static_assert(sizeof(S) != sizeof(S::d)); // true on most platforms
编译器足够聪明,可以知道S
的大小,它不会感到困惑,认为它是sizeof(S::d)
,因为这太愚蠢了。您确实意识到,取恰好是引用的变量的sizeof之间有很大的区别,以一个类型的大小为例,它有一个非静态的数据成员作为引用,对吗?我甚至不理解这个问题。你是在问你是否可以依靠尺寸来告诉你某件东西的正确尺寸?对当然可以。你确实要重新设置它,这样看来明天我就可以拿出我自己的参考实现,它需要200字节,并确保sizeof操作符返回正确的对象大小。你必须使自己的编译器正确吗?请阅读上面Nicol的评论。如果您有struct S{long double&d;}代码>然后sizeof(S)!=sizeof(长双精度)
在大多数平台上。编译器不会感到困惑,它并不愚蠢。它不会通过将sizeof应用于每个成员的结果相加来实现sizeof(S)
,这样它将得到sizeof(S::d)
,这将是引用类型的大小,而不是引用所需的存储空间。除非需要额外的内容,否则不要使用std::endl
<代码>'\n'
开始了新的一行。好的,非常清楚,所以正如Nicol首先指出的,我混淆了类/结构类型的大小和引用变量的大小。投了赞成票(+尼科尔的)好吧,我认为我得到了完美的结果,但事实上没有:我们为什么要做出这样的区分?在sizeof(一个包含ref的类)和sizeof(一个ref)之间?这是我从阅读的所有内容中了解到的:在ref变量的情况下(参见我的示例),编译器将很容易使其完全消失(从而直接打印变量q),然而,在一些其他(比我的更复杂)的情况下,它可能必须跟踪它,因此必须真正创建引用由于这两种情况,我想人们得出结论:“好吧,让我们同意让sizeof(reference)返回被引用对象的大小。如果我的解释是正确的,这是否意味着在包含ref的结构中(您的示例),引用成员是系统地创建的?没有我提到的optim?(使变量消失并直接指向ref对象)?这是我所看到的关于两种尺寸的different@Romain227我花了很长时间才真正理解C++引用,这也是我努力接受C++作为一个有效模型的一部分。也许我那些不知道的信息仍然在困扰着我。声明为引用的变量与var没有什么不同。可声明为值。如果我声明了double d,&rd=d
,则d
和rd
都是double&
类型;如果在需要值的上下文中使用,转换将是自动的。但它们不是不同的东西。但是,将引用放在结构中是不同的。
struct S {
long double& d;
};
static_assert(sizeof(S::d) == sizeof(long double));
static_assert(sizeof(S) != sizeof(S::d)); // true on most platforms