繁体   English   中英

为什么我必须重新解释指针指针?

[英]Why do I Have to reinterpret_cast Pointer Pointers?

所以这个static_cast代码是完全合法的:

int n = 13;
void* pn = static_cast<void*>(&n);
void** ppn = &pn;

然而,必须将其转换为reinterpret_cast以进行编译:

int n = 13;
int* foo = &n;
void** bar = static_cast<void**>(&foo);

如果我不改变它我得到错误:

错误C2440: static_cast :无法从int **转换为void **注意:指向的类型不相关; 转换需要reinterpret_cast ,C风格的转换或函数式转换

所以我认为问题是“类型无关”。 然而我仍然不明白,如果从int*void*是可以的void*它们如何作为int**void**无关?

intvoid无关。 对于int**void**也是如此,因此无法使用static_cast进行转换。

void*但是,很特别 任何数据指针类型(包括int* )都可以是static_castvoid*和back,尽管没有类型与void相关(更进一步,转换为void*不需要static_cast转换,因为它是隐式的)。 int*没有这个属性,也没有void** ,也没有除void*之外的任何其他指针。


已授予void*的额外自由带有额外限制。 void*不能被指向,也不能与指针算法一起使用。 这些限制是唯一可能的,因为永远不会有void类型的对象。 或者从相反的观点来看,由于这些限制, void对象不可能存在。

void**不能给予这些自由,因为它不能给予同样的限制。 它不能被赋予这些限制,因为void*对象确实存在并且它们需要存在。 如果我们不能间接或迭代void** ,那么我们就不能使用void*数组。

void* pn = static_cast<void*>(&n);

是一种隐含的转换; 你也可以写

void *pn = &n;

这意味着pn存储指向某个对象类型的指针; 程序员负责知道该对象类型是什么。 要回送你需要一个static_cast

int *pi = static_cast<int*>(pn);

请注意,使用static_cast转换为与原始明显不同的任何类型( float明显不同, const int不是)是一种重新解释的方法。 您应该拼写reinterpret_cast不是隐式转换(或static_cast ),后跟static_cast

这是void*一个完整目的,一个追溯到C的概念,其中强制转换拼写为C风格的强制转换(不是static_cast ......),但具有相同的含义。

回到C和C ++中的声明语法:

指向int的指针是int (*pi); (括号没用,但有助于说明这一点),你可以这样读:我声明表达式(*pi)类型为int 您可以通过以下方式读取函数声明:in int f(int i); 我声明如果iint类型,那么f(i)类型为int

声明void (*pi); 看起来像是指向void的指针,但是没有类型为void的对象,表达式*pi甚至没有很好地形成,它没有意义。 这是类型系统中的一个特例 :语法表示“指向void的指针”,语义表示“指向某事物的指针”。

在C和C ++中,指针对象是第一个类对象,您可以获取其地址并指向指针等。(与Java对比,其中像其他基本类型的引用不是类对象。)

所以你可以有一个int**int*** ...指向(指针...到int ); 你可以出于同样的原因void** :声明为指向(指向void的指针),语义指向(指向某事物的指针)。

就像指向int的指针一样,无法在没有强制转换的情况下指向float的指针:

float *f = &i; // ill-formed

由于类型不匹配,与void**不同的类型不能分配给void**取消引用void**的结果必须是void*对象

暂无
暂无

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

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