2012-08-08 124 views
3

在C中,void指針被隱式地轉換爲另一種類型。C與C++中void *的轉換

請參見下面的程序:

int main() 
{ 
    void *p; 
    int* ptr,i=5; 
    p=&i; 
    ptr=p; <--------------------------- 
    return 0; 
} 

當C環境下運行的程序compiles successfully

但是,如果在同一個程序爲C下運行++環境下,我得到了下面error

prog.cpp: In function ‘int main()’: 
prog.cpp:8: error: invalid conversion from ‘void*’ to ‘int*’ 

這意味着,在C++中,我們需要明確的典型案例一void指針。

那麼,爲什麼new運算符的返回類型是void *?如何將其轉換爲所需的類型?

+0

我認爲你可以指示C編譯器對於隱式強制轉換更迂腐。 – maba 2012-08-08 13:25:37

回答

3

如果您超載operator new,那麼確實會返回void*。超載operator new基本上是像C.

malloc()一個簡單的分配功能但當你使用操作new,你正在做的不僅僅是調用該函數更多;例如,你也隱式地調用構造函數。返回確切的正確類型是與new構建和超載operator new函數之間的另一個隱含差異。

C++給你一個錯誤,因爲void*可能指向任何東西。所以如果你試圖將它分配給某個具體的東西,那麼你正在做出一個可能並非如此的假設。由於C++是強類型的,所以你必須告訴編譯器你的假設並明確表示它;這是類型安全提供的保護機制。 C不是強類型的,完全由開發人員負責照顧。

+0

+1是的 - 非常同意。應該添加C++是強類型的。 C不是。 – 2012-08-08 13:19:53

1

new運算符由編譯器專門處理,它從參數中獲取類型爲new,並將隱式類型轉換爲正確的類型。

如果您創建了自己的operator new,則必須返回void指針,因爲實際上您不知道類型,只需分配內存量即可。

1

因爲new不是函數,所以它是一個運算符,並且由編譯器專門處理。

1

C++對指針強制轉換施加更嚴格的規則。其中一個原因可能是因爲C++中的指針最終可能會導致機器碼,即它不是一個純粹的化妝品。

例如,類A繼承BC(按此順序)。如果您將指針指向C並將其轉換爲A - 此結果爲(原始)指針移位。

-1

http://www.cplusplus.com/reference/std/new/operator%20new/

運營商新的可以明確地被稱爲一個普通的功能,但在 C++,新是一個非常具體的行爲操作:使用new運算符的表達式 ,首先調用函數operator新其類型說明符的大小爲 作爲第一個參數,如果成功,則 會自動初始化或構造對象(如果需要)。 最後,表達式將作爲指向適當的 類型的指針進行評估。

注意最後一句。

1

您需要輸入:

ptr = (int *) p; 

的新的結果不是一個void *。這取決於你正在創建的對象。 如果你這樣做

ptr = new int [2]; 

有沒有重鑄涉及。

+0

這裏的reinterpret_cast (p)優於C風格演員。 C++提供了不同的轉換操作符,應該使用它們。 – Thelvyn 2012-08-08 13:25:21

+0

避免使用'reinterpret_cast' - 在這種情況下'static_cast'不僅夠用,而且也是可取/推薦的。 – 2012-08-08 13:48:28

0

那麼,爲什麼新操作符的返回類型是void *?

您的意思是關鍵字new,用於像int * p = new int[42];這樣的新表達式中嗎?該表達式具有正確的類型,在此情況下爲int*,因此不需要轉換。您是指內存分配功能operator new()?像malloc(),這是處理原始內存,而不是類型的對象,所以它的返回類型是一個非類型化的void*。它在內部由一個新表達式使用,該表達式知道正在創建的對象的類型,所以一旦對象被完全構建,就可以執行必要的指針轉換。

在極少數情況下,如果您想在自己的代碼中使用它,您必須自己將其轉換爲正確的類型;但你幾乎總是通過新表達式間接使用它,而不必擔心這些細節。