简体   繁体   English

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

[英]static_cast void* char* vs static_cast void** char**

If I do the following all is ok: 如果我做以下一切都没问题:

char* cp = "abc";
void* vp = NULL;
vp = static_cast<void*>(cp);//ok
cp = static_cast<char*>(vp);//ok

But the following is not: 但以下不是:

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 **'

Please can someone explain to me why the second examples are not allowed. 请有人向我解释为什么不允许第二个例子。 Please don't quote the C++ standard as your whole answer, because I've already seen answers that quote it, and I don't understand what they meant. 请不要引用C ++标准作为整个答案,因为我已经看到引用它的答案,我不明白它们的意思。 I want to understand why the second examples don't work (ie. if you could give an example where it would be dangerous that would be a great help). 我想理解为什么第二个例子不起作用(即,如果你能给出一个例子,那将会是一个很大的帮助)。 Because I don't get it. 因为我没有得到它。 To me, both examples are casting pointers. 对我来说,这两个例子都是铸造指针。 Why does an additional level of indirection make any difference? 为什么额外的间接级别会有所不同?

A void * pointer can point at "anything", and it is valid to convert all pointers to a void * , and it is valid to convert all pointers from void * to some other type. void *指针可以指向“任何”,将所有指针转换为void *是有效的,将所有指针从void *转换为其他类型是有效的。

However, a void ** is a pointer that points to a void * value. 但是, void **是指向void *值的指针。 And a char ** is a pointer that points to char * value. char **是一个指向char *值的指针。 These types don't point to the types that are convertible from one another. 这些类型不指向可相互转换的类型。 You can, if you NEED to do this, use void **vpp = reinterpret_cast<void **>(cpp); 如果您需要这样做,可以使用void **vpp = reinterpret_cast<void **>(cpp); , but it's "not safe" (you are basically telling the compiler "Look, I know what I'm doing here, so just do it", which may not do what you actually expected...) ,但它“不安全”(你基本上是在告诉编译器“看,我知道我在这里做什么,所以就这么做”,这可能不会达到你的实际预期......)

The restriction is to avoid breaking the type system. 限制是避免破坏类型系统。 The first conversion is fine: 第一次转换很好:

type *p = ...;
void *vp = p;

While you are giving away the type, you cannot inflict too much damage to the original value without since there is little to be done with a void object and all changes to vp are local to the pointer and cannot affect p . 当你放弃的类型,你不能造成太大的伤害到原来的值,而因为有一点要与做void对象和所有变化vp是本地指针并不能影响p

If the second case was allowed: 如果允许第二种情况:

type **p = ...;
void **vp = p;

Then perfectly looking and correct code could break your application. 那么完美的代码和正确的代码可能会破坏您的应用 For example: 例如:

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!!!

The type system has been subverted. 类型系统已被破坏。

That is, the problem is that in the second case there are operations that can be applied to the destination pointer that can modify the original object and cause bugs. 也就是说,问题在于,在第二种情况下,存在可以应用于可以修改原始对象并导致错误的目标指针的操作。 Similar examples can be found with const other cases (you can convert int* to const int* , but you cannot convert int** to const int** ...). 类似的例子可以在const其他情况下找到(你可以将int*转换为const int* ,但你不能将int**转换为const int** ...)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM