static_cast void* char* vs static_cast void** char**

static_cast void* char* vs static_cast void** char**

本文关键字:char static void cast vs      更新时间:2023-10-16

如果我这样做,一切都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**…)。