static_cast <char *>和(char *)</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*)
是否更安全。如果您有足够的知识,可以告诉我有关该主题的信息吗?
注意:如果您有更好的想法,请帮助我,以便我可以改进我的问题?
答案 0 :(得分:11)
static_cast
比隐式C样式转换更安全。如果你试图转换一个与另一个不兼容的实体,那么static_cast
会给你一个编译时错误,而不像隐式的c风格转换(与隐式c风格的转换不同)。
static_cast
在这里给您一个错误,因为您要说的是int
并尝试将其放入char(一个 int 并尝试将其放在 char 中)
,这是不可能的。 int
需要的内存比char
占用的内存多,并且无法以安全的方式进行转换。
如果你仍然想要实现这一点,你可以使用reinterpret_cast
,它允许你对两种完全不同的数据类型进行类型转换,但它并不安全。
使用reinterpret_cast
获得的唯一保证是,如果将结果转换回原始类型,您将获得相同的值,但没有其他安全保证。
答案 1 :(得分:3)
- 首先 - 您可以轻松搜索
_cast
并找到任何c ++演员。搜索c风格的演员阵容要困难得多。 - 秒 - 如果你使用c ++强制转换,你需要选择正确的。在您的情况下,它是
reinterpret_cast
C风格的演员表演了一切。
你也可以在这里查看:http://www.cplusplus.com/doc/tutorial/typecasting/了解不同c ++演员的差异。我强烈建议只使用c ++强制转换。这样你就可以轻松找到&amp;稍后检查它们,你被迫思考你在那里做了什么。这提高了代码质量!
答案 2 :(得分:1)
static_cast
在这里是非法的;你在无关之间施展 指针类型。将其编译的解决方案是使用 reinterpret_cast
(这是(char*)
在这种情况下解决的问题)。 当然,这告诉您代码不可移植,事实上, 除非你做一些非常低水平的工作,否则可能无法奏效 在所有情况下都正确。
在这种情况下,当然,您正在阅读原始数据,并声称它是一个 unsigned int
。它不是;什么读输入是原始数据,你 仍然需要手动转换为你需要的任何东西,根据 写入文件时使用的格式。 (没有这样的事情 未格式化的数据。只是数据与未记录,未指定,或 未知格式。 “未格式化”的输入和输出 iostream旨在读取和编写您格式化的char
缓冲区 手动。这里reinterpret_cast
的需要是一个明确的警告 您的代码出了问题。 (也有例外 当然,但它们很少而且很远。)
答案 3 :(得分: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风格的演员表很难。
答案 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*>
吓到,因为如果您想将字节写入文件,那么您必须做些什么。
this is my first question :)
I have one pile file, and I have open it like shown below ;
ifstream in ( filename, ios :: binary | ios :: in )
Then, I wish hold 2 byte data in unsigned int hold ;
unsigned int hold; in . read(static_cast<char *>(&hold), 2);
It seems correct to me. However, when I compile it with
g++ -ansi -pedantic-errors -Werror - -Wall -o main main.cpp
Compiler emits error
error: invalid static_cast from type ‘unsigned int*’ to type ‘char*’
Actually, I have solved this problem by changing static_cast with ( char*), that is
unsigned int hold; in . read((char*)(&hold), 2);
My questions are :
- What is the difference(s) between static_cast<char*> and (char*) ?
- I am not sure whether using (char*) is a safer or not. If you have enough knowledge, can you inform me about that topic ?
NOTE : If you have better idea, please help me so that I can improve my question?
static_cast is a safer cast than the implicit C style cast. If you try to cast an entity which is not compatible to another, then static_cast gives you an compilation time error unlike the implicit c-style cast.
static_cast gives you an error here because what you are trying to say is take an int and try to fit it in a char, which is not possible. int needs more memory than what char occupies and the conversion cannot be done in a safe manner.
If you still want to acheive this,You can use reinterpret_cast, It allows you to typecast two completely different data types, but it is not safe.
The only guarantee you get with reinterpret_cast is that if you cast the result back to the original type, you will get the same value, But no other safety guarantees.
浅析c++中的类型转换--static_cast
谷歌编程规范指出,要使用c++的类型转换操作符,如static_cast。而坚决抵制c语言中的强制类型转换,例如int y = (int)x。
所以,今天就来八一八c++中的类型转换。
其中c++类型转换运算符有:
static_cast
dynamic_cast
const_cast
reinterpret_cast
今天主要深入分析static_cast的用法。
微软是这样描述的:
Converts an expression to the type of type-id, based only on the types that are present in the expression.
语法如下:
static_cast ( expression )
似乎有些空洞。直白的说,static_cast操作符可用于将一个指向基类的指针转换为指向子类的指针。但是这样的转换不总是安全的。
一般情况下,你可以使用static_cast用于数字类型的转换,如把枚举转换为int或是 float类型。
之所以讲static_cast不够安全,就是指在运行阶段不进行类型检查(和dynamic_cast相比,但是dynamic_cast也有一定的局限性,我们以后再讨论)。
具体用法:
①用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。
进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;
进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。
②用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。
③把空指针转换成目标类型的空指针。
④把任何类型的表达式转换成void类型。
注意:static_cast不能转换掉expression的const、volatile、或者__unaligned属性。
光说不练不行,下面就写几个使用static_cast的应用代码。
typedef unsigned char BYTE;
void f() {
char ch;
int i = 65;
float f = 2.5;
double dbl;
ch = static_cast<char>(i); // int to char
dbl = static_cast<double>(f); // float to double
i = static_cast<BYTE>(ch);
}
// static_cast_Operator_2.cpp
// compile with: /LD /GR
class B {
public:
virtual void Test(){}
};
class D : public B {};
void f(B* pb) {
D* pd1 = dynamic_cast<D*>(pb);
D* pd2 = static_cast<D*>(pb);
关于static_cast的用法就写这些。再之后多博客中,我们将陆续讲述其他几种类型转换操作符,并与static_cast进行对比。