C++ 静态\u强制作废*字符*与静态\u强制作废**字符**

C++ 静态\u强制作废*字符*与静态\u强制作废**字符**,c++,casting,static-cast,C++,Casting,Static Cast,如果我执行以下操作,则一切正常: char* cp = "abc"; void* vp = NULL; vp = static_cast<void*>(cp);//ok cp = static_cast<char*>(vp);//ok char*cp=“abc”; void*vp=NULL; vp=静态施法(cp)//好啊 cp=静态施法(vp)//好啊 但以下情况并非如此: char** cpp = &cp; void** vpp = NULL; vpp =

如果我执行以下操作,则一切正常:

char* cp = "abc";
void* vp = NULL;
vp = static_cast<void*>(cp);//ok
cp = static_cast<char*>(vp);//ok
char*cp=“abc”;
void*vp=NULL;
vp=静态施法(cp)//好啊
cp=静态施法(vp)//好啊
但以下情况并非如此:

char** cpp = &cp;
void** vpp = NULL;
vpp = static_cast<void**>(cpp);//error C2440: 'static_cast':
                               //cannot convert from 'char **' to 'void **'
cpp = static_cast<char**>(vpp);//error C2440: 'static_cast':
                               //cannot convert from 'void **' to 'char **'
char**cpp=&cp;
void**vpp=NULL;
vpp=静态_-cast(cpp)//错误C2440:“静态_cast”:
//无法从“char**”转换为“void**”
cpp=静态投影(vpp)//错误C2440:“静态_cast”:
//无法从“void**”转换为“char**”

请有人向我解释为什么第二个例子是不允许的。请不要引用C++标准作为你的答案,因为我已经看到了答案,我不明白它们的意思。我想理解为什么第二个例子不起作用(即,如果你能举一个危险的例子,那将是一个很大的帮助)。因为我不明白。对我来说,这两个例子都是铸造指针。为什么额外级别的间接寻址会有任何不同?

指针可以指向“任何东西”,将所有指针转换为
void*
都是有效的,将所有指针从
void*
转换为其他类型也是有效的


但是,
void**
是指向
void*
值的指针。而
char**
是指向
char*
值的指针。这些类型不指向可相互转换的类型。如果需要,可以使用
void**vpp=reinterpret\u cast(cpp),但它是“不安全的”(你基本上是在告诉编译器“看,我知道我在做什么,所以就这么做吧”,这可能不会达到你的实际期望…

限制是为了避免破坏类型系统。第一次转换很好:

type *p = ...;
void *vp = p;
当您放弃类型时,您不能对原始值造成太大的损害,因为
void
对象几乎没有什么可以做的,并且对
vp
的所有更改都是指针的本地更改,并且不会影响
p

如果允许第二种情况:

type **p = ...;
void **vp = p;
那么,外观完美且正确的代码可能会破坏您的应用程序。例如:

int *parray[10];
int **p = parray;
void **vp = p;
*vp = new double();  // now parray[0] is a pointer to a double object, 
                     // not a pointer to an int!!!
类型系统已被破坏


也就是说,问题在于,在第二种情况下,有一些操作可以应用于目标指针,这些操作可以修改原始对象并导致错误。类似的例子可以在
const
其他情况下找到(您可以将
int*
转换为
const*
,但不能将
int**
转换为
const int**

您可以隐式转换任何指向
void*
的指针,并反向进行静态强制转换。但通常情况下,
T*
U*
是不相关的。(现在想想
T=char*
U=void*
)你可以将
char**
转换为
void*
,反之亦然。@Kerrek SB-是的,但为什么不允许这样做?什么时候会不安全?对不起,我还是不明白。如果某个字符串的地址为0x12345678,我可以将其放入我的char*或void*中。如果我的char*的地址是0x87654321,为什么我不能将该值(地址0x87654321)放入我的void**?也就是说,为什么可以将0x12345678静态转换为空*,但不可以将0x87654321静态转换为空*?什么时候/为什么这会不安全?@e244:问题是如果允许转换,您可以很容易地(并且没有任何显式转换)破坏类型系统。我提供了一个较长的解释作为答案,但简短的描述是,双指针允许您以不安全的方式更改数据。
void*
能否指向函数(即函数指针是否可转换为
void*
)?@rubenvb:标准不保证,问题在于,在某些平台上,代码和数据的地址空间可能大小不同