static_cast<字符*>和(字符*)之间的区别
Difference between static_cast<char*> and (char*)
这是我的第一个问题:)
我有一个堆文件,我像下面这样打开它;
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*)
是否更安全。如果你有足够的知识,你能告诉我关于这个话题吗?
注:如果你有更好的想法,请帮助我,以便我可以改进我的问题。
static_cast
是一种比隐式C风格强制转换更安全的强制转换。如果你试图将一个不兼容的实体强制转换为另一个实体,那么static_cast
会给你一个编译时间错误,而不像隐式的c风格强制转换。
static_cast
在这里给你一个错误,因为你想说的是采取int
并尝试将其适合char
,这是不可能的。int
需要比char
占用更多的内存,并且不能以安全的方式进行转换。
如果你仍然想实现这一点,你可以使用reinterpret_cast
,它允许你类型转换两种完全不同的数据类型,但它不安全。
使用reinterpret_cast
的唯一保证是,如果您将结果强制转换回原始类型,您将获得相同的值,但没有其他安全保证。
- 首先-您可以轻松搜索
_cast
并找到任何c++强制转换。搜索c风格的强制转换要困难得多。 - 第二—如果您使用c++强制转换,则需要选择正确的强制转换。在您的情况下,它是
reinterpret_cast
。
c风格的强制转换做了一切。
您也可以在这里查看:http://www.cplusplus.com/doc/tutorial/typecasting/了解不同c++类型转换的差异。我强烈建议只使用c++强制类型转换。这样你就可以很容易地找到&稍后再检查它们,你就会被迫思考自己到底在做什么。这提高了代码质量!
您应该使用reinterpret_cast<char *>
而不是static_cast<char *>
,因为数据类型不相关:您可以在指针之间转换子类到超类,例如,或在int
和long
之间,或在void *
和任何指针之间,但unsigned int *
到char *
不是"安全"的,因此您不能使用static_cast
。
区别在于c++中有各种类型的强制转换:
-
static_cast
,用于"安全"转换; -
reinterpret_cast
用于"不安全"转换; -
const_cast
,用于删除const
属性; -
dynamic_cast
用于向下转换(将指针/引用从超类转换为子类)。
C风格的强制转换(char *)x
可以表示以上所有这些,因此它不像c++强制转换那样清晰。此外,搜索c++风格的强制转换很容易(只搜索_cast
),但搜索所有C风格的强制转换相当困难。
这里的static_cast
是非法的;你在不相关的人之间进行选择指针类型。使其编译的解决方案是使用reinterpret_cast
(这是(char*)
在本例中解析到的)。当然,这告诉你代码是不可移植的,事实上,除非你做的是一些非常低级的工作,否则可能行不通在所有情况下都正确。
在这种情况下,当然,您正在读取原始数据,并声明它是一个unsigned int
。事实并非如此;读取输入的是原始数据,您可以仍然需要手动转换成任何你需要的,根据写入文件时使用的格式。)没有所谓的非格式化数据。仅包含未记录、未指定或未知格式。unformatted&rdquo的;输入和输出iostream被设计为读写你格式化的char
缓冲区手动。这里需要reinterpret_cast
是一个明确的警告你的代码有问题。(当然也有例外当然,但他们很少。)
在使用ifstream或ofstream或fstream进行二进制文件I/O时,通常会得到这些错误。问题是这些流的方法采用const char*
,而你拥有的是其他类型的数组。您希望将数组以二进制位的形式写入到文件中。
这样做的传统方法是使用旧式的cast (char*)
,它基本上只是说,无论我把它当作(char*)
的指针。迂腐/严格的模式不鼓励旧式的类型转换。为了消除这些警告,c++ 11的等效代码是reinterpret_cast<const char*>
。
我想说,如果你正在做二进制文件I/O,那么你已经知道东西可能是可移植的,也可能不是,这取决于你如何在一个操作系统中保存文件,并在另一个操作系统中读取。这完全是另一个问题,但是,不要被reinterpret_cast<const char*>
吓到,因为这是你必须做的,如果你想写字节文件
- 使用.find函数在c++中查找字符和另一个字符之间的大小
- 函数签名与调用的函数不匹配,常量字符[]和字符*之间的区别?
- 相同字符之间的最小距离
- 常量字符 [] 和常量字符*之间的区别
- 字符* 和 std::字符串和常量字符*之间的转换
- 为什么常量字符[]和常量字符*之间的比较不同
- 字符* 和无符号字符* 之间不兼容
- 文件名如何在"char"和2字节字符之间工作
- 如何在多个不同字符之间获取多个字符串
- 如何从两个字符之间的文件中提取整数
- 删除两个字符之间的文本
- 在代表 UTF8 的有符号字符和无符号字符之间进行转换
- 在屏幕上拼接的字符之间创建空格 - SDL
- 参数表中字符 [N] 和字符 (&)[N] 之间的区别
- 从隐藏在随机字符之间的文件中提取整数
- 字符串中字符之间的空格
- 常量字符 [] 和字符 [] 之间的区别
- 将两个 '' 字符之间的子字符串提取到单独的数组中
- 为什么我不能在字符 * 和无符号字符 * 之间static_cast?
- 从 c++ 到 Java 行的命名管道连接,每个字符之间有空格