C++ 静态_cast<;字符*>;和(字符*)

C++ 静态_cast<;字符*>;和(字符*),c++,file,C++,File,这是我的第一个问题:) 我有一个堆文件,我打开它,如下所示 ifstream in ( filename, ios :: binary | ios :: in ) 然后,我希望在unsigned int hold中保存2字节的数据 unsigned int hold; in . read(static_cast<char *>(&hold), 2); 编译器发出错误 error: invalid static_cast from type ‘unsigned int

这是我的第一个问题:)

我有一个堆文件,我打开它,如下所示

ifstream in ( filename,  ios :: binary | ios :: in ) 
然后,我希望在unsigned int hold中保存2字节的数据

unsigned int hold;
in . read(static_cast<char *>(&hold), 2); 
编译器发出错误

error: invalid static_cast from type ‘unsigned int*’ to type ‘char*’ 
实际上,我已经通过使用(char*)更改静态_cast解决了这个问题,即

unsigned int hold;
in . read((char*)(&hold), 2); 
我的问题是:

  • static\u cast
    (char*)
    之间有什么区别
  • 我不确定使用
    (char*)
    是否更安全。如果你有足够的知识,你能告诉我这个话题吗
注意:如果您有更好的想法,请帮助我改进我的问题?

    第一,你可以很容易地搜索<代码> .xase>代码>,找到任何C++的Casic。搜索c样式转换要困难得多 第二种——如果你使用C++的强制转换,你需要选择正确的。在您的情况下,它是
    reinterpret\u cast

    c型演员什么都做

你也可以在这里检查:对于不同的C++版本的差异。我强烈建议只使用C++的转换。通过这种方式,你可以很容易地找到并在以后检查它们,你被迫思考你在那里实际做了什么。这提高了代码质量

静态类型转换
比隐式C样式转换更安全。如果您试图强制转换与另一个实体不兼容的实体,则与隐式c样式强制转换不同,
static\u cast
会给您一个编译时错误

static\u cast
在这里给您一个错误,因为您试图说的是取一个
int
并尝试将其放入
char
,这是不可能的
int
需要比
char
占用的内存更多的内存,并且无法以安全的方式进行转换

如果您仍想实现此目的,可以使用
重新解释\u cast
,它允许您键入两种完全不同的数据类型,但并不安全。

使用
reinterpret\u cast
可以得到的唯一保证是,如果您将结果转换回原始类型,您将获得相同的值,但没有其他安全保证。

您应该使用
reinterpret\u cast
而不是
静态\u cast
,因为数据类型不相关:例如,您可以在指向子类的指针到超类之间转换,或者在
int
long
之间转换,或者在
void*
和任何指针之间转换,但是
unsigned int*
char*
是不“安全”的,因此您不能使用
static\u cast
进行转换

P>差异在于C++中有各种类型的转换:

  • static\u cast
    用于“安全”转换

  • reinterpret\u cast
    用于“不安全”转换

  • const\u cast
    用于删除
    const
    属性

  • dynamic_cast
    用于向下转换(将指针/引用从超类转换为子类)


<> > C风格的Case>代码>(char *)x<代码>可以表示所有这些,因此它不像C++的Cask那么清晰。此外,很容易对C++风格的强制转换进行grep(只对
\u cast
进行grep),但很难搜索所有C风格的强制转换。

这里的
静态\u cast
是非法的;你在不相关的 指针类型。让它编译的解决方案是使用
reinterpret\u cast
(在本例中,
(char*)
解析为这一点)。 这当然告诉你代码是不可移植的事实上, 除非你在做一些非常低级的工作,否则很可能是行不通的 在所有情况下都是正确的

当然,在本例中,您正在读取原始数据,并声称它是
无符号整数
。但事实并非如此;读取的输入是原始数据,您可以 仍然必须手动转换为您需要的任何内容,根据 写入文件时使用的格式。(世上没有 未格式化数据。仅包含未记录、未指定或 未知格式。中的“未格式化”输入和输出 iostream设计用于读取和写入格式化的
char
缓冲区 手动操作。
重新解释演员表的需要这里有一个明确的警告
你的代码有问题。(当然,也有例外。)

当然,但它们很少。)

在使用ifstream、ofstream或fstream进行二进制文件I/O时,通常会出现这些错误。问题是这些流的方法采用
const char*
,而您拥有的是其他类型的数组。您希望将数组作为二进制位写入文件中

传统的方法是使用旧式cast
(char*)
,基本上就是说,无论我把它当作什么指针,它都是
(char*)
。旧式的cast是不受欢迎的。为了消除这些警告,C++11等价物是
重新解释cast


我想说,如果你正在进行二进制文件I/O,那么你已经知道事情可能是可移植的,也可能不是可移植的,这取决于你在一个操作系统中保存文件和在另一个操作系统中读取文件的方式。然而,这完全是另一个问题,不要被
重新解释cast
吓到,因为如果你想将字节写入文件,你必须这样做。

+1lanation,但我在这里要提到
重新解释cast
const\u cast
不仅适用于cast
const
,也适用于不太常见的
volatile
。@Andrearbgia:注意
const\u cast
还可以添加
const
volatile
限定符。(当然,在很多情况下,这并不是很有用。)C风格的cast与
dynamic\u cast
(除了
static\u cast
dynamic\u cast
都做了与隐式转换相同的事情)和
static\u castunsigned int hold;
in . read((char*)(&hold), 2);