这是我的第一个问题:)
我有一个堆文件,我打开它,如下所示;
ifstream in ( filename, ios :: binary | ios :: in )
然后,我希望在unsigned int hold中保存2字节数据;
unsigned int hold;
in . read(static_cast<char *>(&hold), 2);
对我来说似乎是对的。但是,当我用
编译它时g++ -ansi -pedantic-errors -Werror - -Wall -o main main.cpp
编译器发出错误
error: invalid static_cast from type ‘unsigned int*’ to type ‘char*’
实际上,我通过使用(char *)更改static_cast来解决了这个问题,即
unsigned int hold;
in . read((char*)(&hold), 2);
我的问题是:
static_cast<char*>
和(char*)
之间的区别是什么?(char*)
是否更安全。如果您有足够的知识,可以告诉我有关该主题的信息吗?注意:如果您有更好的想法,请帮助我,以便我可以改进我的问题?
答案 0 :(得分:11)
static_cast
比隐式C样式转换更安全。如果你试图转换一个与另一个不兼容的实体,那么static_cast
会给你一个编译时错误,而不像隐式的c风格转换。
static_cast
在这里给您一个错误,因为您要说的是int
并尝试将其放入char
,这是不可能的。 int
需要的内存比char
占用的内存多,并且无法以安全的方式进行转换。
如果你仍然想要实现这一点,你可以使用reinterpret_cast
,它允许你对两种完全不同的数据类型进行类型转换,但它并不安全。
使用reinterpret_cast
获得的唯一保证是,如果将结果转换回原始类型,您将获得相同的值,但没有其他安全保证。
答案 1 :(得分:3)
_cast
并找到任何c ++演员。搜索c风格的演员阵容要困难得多。reinterpret_cast
C风格的演员表演了一切。你也可以在这里查看:http://www.cplusplus.com/doc/tutorial/typecasting/了解不同c ++演员的差异。我强烈建议只使用c ++强制转换。这样你就可以轻松找到&amp;稍后检查它们,你被迫思考你在那里做了什么。这提高了代码质量!
答案 2 :(得分:1)
您应该使用reinterpret_cast<char *>
而不是static_cast<char *>
,因为数据类型不相关:例如,您可以在指向子类的指针与超类之间转换,或者在int
之间转换和long
,或void *
与任何指针之间,但unsigned int *
到char *
不是“安全”,因此您无法使用static_cast
。< / p>
不同之处在于,在C ++中,您有各种类型的强制转换:
static_cast
用于“安全”转换;
reinterpret_cast
用于“不安全”转换;
const_cast
用于删除const
属性;
dynamic_cast
用于向下转换(将指针/引用从超类转换为子类)。
C风格的演员(char *)x
可能意味着上述所有这些,所以它不像C ++演员那样清晰。此外,很容易grep for C ++风格的演员表(只有grep for _cast
),但搜索所有C风格的演员表很难。
答案 3 :(得分:1)
static_cast
在这里是非法的;你在无关之间施展
指针类型。将其编译的解决方案是使用
reinterpret_cast
(这是(char*)
在这种情况下解决的问题)。
当然,这告诉您代码不可移植,事实上,
除非你做一些非常低水平的工作,否则可能无法奏效
在所有情况下都正确。
在这种情况下,当然,您正在阅读原始数据,并声称它是一个
unsigned int
。它不是;什么读输入是原始数据,你
仍然需要手动转换为你需要的任何东西,根据
写入文件时使用的格式。 (没有这样的事情
未格式化的数据。只是数据与未记录,未指定,或
未知格式。 “未格式化”的输入和输出
iostream旨在读取和编写您格式化的char
缓冲区
手动。这里reinterpret_cast
的需要是一个明确的警告
您的代码出了问题。 (也有例外
当然,但它们很少而且很远。)
答案 4 :(得分:0)
通常使用ifstream或ofstream或fstream在二进制文件I / O期间会出现这些错误。问题是这些流的方法采用const char*
,而你拥有的是其他类型的数组。您希望将数组作为二进制位写入文件。
传统的做法是使用旧式的演员(char*)
,基本上只是说我把它当作(char*)
对待的指针。 pedantic/strict mode不鼓励旧式演员阵容。为了摆脱这些警告,C ++ 11的等价物为reinterpret_cast<const char*>
。
我想说,如果您正在进行二进制文件I / O,那么您已经知道可能会或可能不会移植,具体取决于您如何在一个操作系统中保存文件并在另一个操作系统中读取。然而,这又是另一个问题,不会被reinterpret_cast<const char*>
吓到,因为如果您想将字节写入文件,那么您必须做些什么。