如果我执行以下操作即可:
char* cp = "abc";
void* vp = NULL;
vp = static_cast<void*>(cp);//ok
cp = static_cast<char*>(vp);//ok
但以下不是:
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 **'
请有人向我解释为什么不允许第二个例子。请不要引用C ++标准作为整个答案,因为我已经看到引用它的答案,我不明白它们的意思。我想理解为什么第二个例子不起作用(即,如果你能给出一个例子,那将会是一个很大的帮助)。因为我没有得到它。对我来说,这两个例子都是铸造指针。为什么额外的间接级别会有所不同?
答案 0 :(得分:12)
void *
指针可以指向“任何”,并且将所有指针转换为void *
是有效的,将所有指针从void *
转换为其他指针是有效的类型。
但是,void **
是指向void *
值的指针。 char **
是一个指向char *
值的指针。这些类型不指向可相互转换的类型。你可以,如果你需要这样做,使用void **vpp = reinterpret_cast<void **>(cpp);
,但它“不安全”(你基本上是在告诉编译器“看,我知道我在这里做什么,所以就这样做”,这可能是不要做你真正期望的事情......)
答案 1 :(得分:6)
限制是避免破坏类型系统。第一次转换很好:
type *p = ...;
void *vp = p;
当您放弃该类型时,您不能对原始值造成太多损害,因为void
对象几乎无法完成vp
所有更改1}}是指针的本地,不会影响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*
,但无法将int**
转换为const int**
...)。< / p>