C++ 简单c++;指针铸造

C++ 简单c++;指针铸造,c++,pointers,casting,C++,Pointers,Casting,谁能给我解释一下: char* a; unsigned char* b; b = a; // error: invalid conversion from ‘char*’ to ‘unsigned char*’ b = static_cast<unsigned char*>(a); // error: invalid static_cast from type ‘char*’ to type ‘unsigned char*’ b = static_cast<unsigne

谁能给我解释一下:

char* a;
unsigned char* b;

b = a;
// error: invalid conversion from ‘char*’ to ‘unsigned char*’

b = static_cast<unsigned char*>(a);
// error: invalid static_cast from type ‘char*’ to type ‘unsigned char*’

b = static_cast<unsigned char*>(static_cast<void*>(a));
// everything is fine
char*a;
无符号字符*b;
b=a;
//错误:从“字符*”到“无符号字符*”的转换无效
b=静态铸件(a);
//错误:从类型“char*”到类型“unsigned char*”的静态\u转换无效
b=静态施法(静态施法(a));
//一切都很好
第二组和第三组的区别是什么?如果3中的方法用于其他(更复杂的)类型,是否存在任何陷阱

[编辑] 正如一些人提到的糟糕的设计等

这个简单的例子来自一个图像库,它给了我一个指向图像数据的指针,如
char*
。很明显,图像强度总是正的,所以我需要将其解释为无符号字符数据。

static\u cast
消除了类型检查的目的,正如您所说,现在它指向了“您不知道的类型”。然后编译器必须信任你,当你对你的新
void*
static\u cast
时,他会按照你明确的要求去做他的工作


如果你真的必须在这里使用强制转换,你最好使用
reinterpret\u cast
(因为这里明显显示了一个设计问题)。

C++试图比C对类型强制转换有一点限制,所以它不允许你使用
static\u cast
将字符转换为无符号字符(注意,你会丢失符号信息)。然而,类型<代码> VUL**/COD>是特殊的,因为C++不能对其作出任何假设,并且必须依赖编译器告诉它确切的类型(因此第三个CAST作品)。
至于你的第二个问题,当然在使用
void*
时有很多陷阱。通常,您不必使用它,因为C++类型的系统、模板等都足够丰富,不必依赖于“未知类型”。另外,如果你真的需要使用它,你必须非常小心地使用从
void*
的强制转换来控制插入的类型和获得的类型实际上是相同的(例如,不是指向子类的指针等)。

2和3之间的区别在于3,您明确地告诉编译器通过强制转换为void*停止检查您。如果3中的方法用于几乎任何不是直接原语整型的东西,您将调用未定义的行为。无论如何,您都可以在#3中调用未定义的行为。如果它不是隐式强制转换,除非你真的知道发生了什么,否则这几乎肯定是个坏主意,如果你将void*强制转换回不是它的原始类型,你将得到未定义的行为。

静态\u指针之间的强制转换只有在其中一个指针是void或者在类的对象之间进行强制转换时才是正确的,一个类被另一个类继承。

指针之间的强制转换需要重新解释强制转换,但
无效*
除外:

从任何指向
void*
的指针强制转换都是隐式的,因此不需要显式强制转换:

char* pch;
void* p = pch;
void*
到任何其他指针的强制转换只需要
静态强制转换

unsigned char* pi = static_cast<unsigned char*>(p);
unsigned char*pi=static_cast(p);

<代码> > p>您的第三方法之所以有效,是因为C++允许空指针通过<代码> STATICORCAST (并且再次返回)被转换为<代码> T*<代码>,但出于安全原因,其他指针类型更具限制性。code>char
unsigned char
是两种不同的类型。这需要重新解释强制转换

注意,当您强制转换为void*时,您会丢失任何类型信息

你试图做的是不正确的、错误的、容易出错的和误导性的。这就是编译器返回编译错误的原因:-)

一个简单的例子

char* pChar = NULL; // you should always initalize your variable when you declare them
unsigned char* pUnsignedChar = NULL; // you should always initalize your variable when you declare them

char aChar = -128;
pChar = &aChar;
pUnsignedChar = static_cast<unsigned char*>(static_cast<void*>(pChar));
char*pChar=NULL;//声明变量时,应始终初始化变量
无符号字符*pUnsignedChar=NULL;//声明变量时,应始终初始化变量
char-aChar=-128;
pChar=&aChar;
pUnsignedChar=静态_cast(静态_cast(pChar));
然后,尽管我们有
*pUnsignedChar==pChar
但我们有
*pUnsignedChar==255
*pChar==128


我相信这是一个糟糕的笑话,因此代码也很糟糕。

+1又好又短。此外,值得一提的是,
static\u cast
不能丢弃常量。该标准允许您使用
static\u cast
t*
转换到
void*
并返回到
t*
。从
void*
强制转换为与原始指针不同的类型的结果在标准中没有定义。但这正是强制转换的目的:),请参见我的编辑号。
reinterpret\u cast
的目的与您所做的相同,是在您真正了解对象背后的类型时使用。在您的示例中,您显然共享了信息。既然你问过这个问题,那么你显然是C++初学者,否则你应该知道,<>代码> RealTytRask只在真正知道你做什么的时候才用在极限极限中。不,我写的时候知道你必须学习,所以我花了一些时间来回答你不同于其他人。在C++中总是有东西要学,我几乎每天都在学习…我可以向你保证,我仍然觉得自己比C++中的“专家”更“中间”,而且我已经在10年多了。这样一种几乎是初学者总是在学习。我读过你的编辑。我在下面发表了评论,因为我完全不同意你的观点。请注意,在你的问题中,你提出了陷阱,所以我给了你一个具体的例子。但由于重新解释cast通常是不好的做法,您会发现(比您想象的更早)有人警告您,甚至要求您更改代码。只要知道这一点:它是一个基本的C++知识。+ 1也注意到,编译器将接受代码,在所有的场景中,我都能想到它会工作,标准允许<代码> StistaCase <代码> Value*/Cuff>并返回到相同的类型,即