簡體   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