C++如何用引用进行转换工作
C++ how does cast with reference work?
有人能解释一下下面代码中发生了什么吗?
char cd[1024];
unsigned short int & messageSize =reinterpret_cast<unsigned short int&>(*cd);
它是否通过引用获取cd的前2个字符,并将其强制转换为16位int?当我删除'&'时,编译器抱怨无法从char转换为无符号短int。
unsigned short int messageSize =reinterpret_cast<unsigned short int>(*cd);
reinterpret_cast
的"直观"含义是"取一个比特序列,并将其视为该比特序列具有不同的类型"。对于类型char
和unsigned short
,这是不可能的,因为它们具有不同的宽度。
对于第一种情况,直觉是:reinterpret_cast
将左值引用视为指向其引用的类型的指针(并将上述转换应用于该指针(。
从形式上讲,标准上说:
4.2数组到指针的转换[conv.Array]
- 类型为"N T的数组"或"T的未知边界的数组"的左值或右值可以转换为类型为"指向T的指针"的prvalue。结果是指向数组的第一个元素的指针
和:
5.3.1一元运算符[expr.Unary.op]
- 一元
*
运算符执行间接操作:应用它的表达式应该是指向对象类型的指针,或者是指向函数类型的指针并且结果是指向对象或函数的左值表达式所指向的。如果表达式的类型为"指向T的指针",则结果的类型为"T">
因此,在取消引用*cd
之后,我们将获得类型为char
的左值(与编写cd[0]
时相同(。
5.2.10重新解释cast[expr.Reinterpret.cast]
- 如果类型为"pointer to T1"的表达式可以使用
reinterpret_cast
显式转换为类型为"pointer to T2",则类型为T1的glvalue表达式可以强制转换为类型"reference to T2"。结果引用的对象与源glvalue相同,但具有指定的类型。[注意:也就是说,对于lvalues,引用强制转换reinterpret_cast<T&>(x)
与具有内置&
和*
运算符的转换*reinterpret_cast<T*>(&x)
具有相同的效果(对于reinterpret_cast<T&&>(x)
也是如此(。--结束注释]不创建临时,不进行复制,也不调用构造函数(12.1(或转换函数(12.3(
这意味着,你有类似的东西
*reinterpret_cast<unsigned short *>(&cd[0])
但也许比以上所有内容更重要的是:
3.10 Lvalue和右值[basic.lval]
如果程序试图通过不是以下类型之一的glvalue行为未定义:
- 对象的动态类型
- 对象的动态类型的cv限定版本
- char或无符号char类型
也就是说,将"对char的引用"绑定到"unsigned short"类型的对象是可以的。但反之亦然(即,在您的示例中(是不可以的,因为访问这样的引用会调用未定义的行为。
带引用的强制转换与不带引用的同一强制转换有一点不同——不带引用强制转换会创建一个新的临时对象,而带引用强制执行会更改现有对象的类型。这在很多情况下都很重要,例如,在您的情况下,因为您将结果分配给了一个非常数引用。非常量引用不能用临时对象进行初始化。
顺便说一句,你知道你在这里所做的是违反了类型别名规则,这会产生未定义的行为吗?
reinterpret_cast<unsigned short int&>(*cd);
类似于
*reinterpret_cast<unsigned short int*>(cd);
unsigned short int & messageSize
意味着messageSize
是unsigned short int
类型的变量,将存储该变量的内存区域应作为初始值设定项。
初始化器=reinterpret_cast<unsigned short int&>(*cd)
说:取cd
指向的位置的内存,并假装它包含一个unsigned short int
。
结果是,如果您尝试读取和写入messageSize
,那么您将尝试在包含其他内容的内存位置中读取和写入一个unsigned short int
。这会导致未定义的行为。
在一些情况下,假装内存位置包含一个实际上没有的对象是可以的;这不是其中之一。
如果您的编译器没有执行别名优化,则可能会显示为,就好像您的代码目前"工作"一样。然而,代码被破坏了。
- 如何定义在用作函数参数时工作的类模板的转换
- 将双精度值转换为 char 变量时字符串流如何工作
- 隐式转换是否应该在模板参数的上下文中工作?
- strcmp/char* 转换无法按预期工作
- 如何在 Poco 中将工作 HTTP 代码转换为 HTTPS
- Qt-工作线程崩溃时将cv::Mat转换为QImage
- 我的代码在作为参数传入 .begin() 时不起作用,但在我将 .begin() 转换为迭代器后工作
- 字符串文字到 char 数组的转换如何在C++中实际工作
- 将缓冲区转换为在现有程序中工作的iStream
- 更新MySQL连接器后,隐式转换停止工作
- 为什么Arduino(小端序)上的Sha1在没有转换为大端序的情况下工作?
- 如何使转换功能工作?
- 以下对二进制转换代码的小数如何工作
- 隐式转换未按预期工作
- 尝试将工作python程序转换为C++但不起作用
- 字符串到字符指针的转换如何在C++中工作
- 如何将负数转换为更广泛的类型在内部工作
- 十六进制、二进制和 oct 到 dec 转换器无法正常工作C++
- C++到C的转换工作流程
- C++如何用引用进行转换工作