static_cast void* char* vs static_cast void** char**
static_cast void* char* vs static_cast void** char**
如果我这样做,一切都ok:
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++标准作为你的全部答案,因为我已经看到了一些引用它的答案,我不明白它们是什么意思。我想了解为什么第二个例子不起作用(即。如果你能举一个危险的例子,那就太好了。因为我不明白。对我来说,这两个例子都是类型转换指针。为什么额外的间接程度会有什么不同呢?
一个void *
指针可以指向"任何",并且可以将所有指针转换为void *
,并且可以将所有指针从void *
转换为其他类型。
然而,void **
是指向void *
值的指针。char **
是指向char *
值的指针。这些类型不指向可相互转换的类型。你可以,如果你需要这样做,使用void **vpp = reinterpret_cast<void **>(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*
,但您不能将int**
转换为const int**
…)。