[英]Conversion of void* in C vs C++
在C語言中, void
指針隱式地轉換為另一種類型。
參見以下程序:
int main()
{
void *p;
int* ptr,i=5;
p=&i;
ptr=p; <---------------------------
return 0;
}
在C環境下運行時,程序可以成功編譯 。
但是,如果同一程序在C ++環境下運行,我將收到以下錯誤 :
prog.cpp: In function ‘int main()’:
prog.cpp:8: error: invalid conversion from ‘void*’ to ‘int*’
這意味着在C ++中,我們需要顯式地將void
指針鍵入大小寫。
那么,為什么new
運算符的返回類型為void *? 如何將其轉換為所需的類型?
如果重載operator new
,則確實會返回void*
。 重載的operator new
基本上是一個簡單的分配函數,如C中的malloc()
。
但是,當您使用運算符new
,您所做的不僅是調用該函數;還包括 例如,您還隱式調用了構造函數。 返回精確正確的類型是使用new
構造和您的重載operator new
函數之間的另一個隱式差異。
C ++給您一個錯誤,因為void*
可能指向任何東西 。 因此,如果您嘗試將其分配給特定的東西,那么您所做的假設可能不正確。 由於C ++是強類型的,因此您必須告訴編譯器您的假設,並對其進行明確說明。 這就是類型安全提供的保護機制。 C的類型不是強類型,開發人員有責任保重。
編譯器對new
運算符進行了特殊處理,它從參數中獲取類型為new
並將其隱式轉換為正確的類型。
如果您創建自己的operator new
,則必須返回一個void
指針,因為您實際上不知道類型,而只是需要分配的內存量。
因為new
不是函數,所以它是一個運算符,由編譯器專門處理。
C ++對指針強制轉換施加了更嚴格的規則。 原因之一可能是因為用C ++強制轉換的指針最終可能會導致生成機器代碼,即,這並不是純粹的修飾。
例如,類A
繼承了B
和C
(按此順序)。 如果將指針指向C
並將其強制轉換為A
這將導致(原始)指針移位。
您需要輸入:
ptr = (int *) p;
new的結果不是無效*。 這取決於您要創建的對象。 如果你這樣做
ptr = new int [2];
不涉及重鑄。
那么,為什么新運算符的返回類型為void *?
您的意思是關鍵字new
,用於int * p = new int[42];
類的new表達式中嗎? ? 該表達式具有正確的類型,在這種情況下為int*
,因此無需進行轉換。
還是您是指內存分配函數operator new()
? 像malloc()
一樣,它處理的是原始內存,而不是類型化的對象,因此它的返回類型是未類型化的void*
。 它由一個new表達式在內部使用,它知道要創建的對象的類型,因此一旦對象完全構建后就可以執行必要的指針轉換。
在極少數情況下,您想在自己的代碼中使用它,則必須自己將其轉換為正確的類型。 但是您幾乎總是會通過new表達式間接使用它,而不必擔心這些細節。
http://www.cplusplus.com/reference/std/new/operator%20new/
可以將new運算符顯式地作為常規函數調用,但是在C ++中,new是一個具有非常特定行為的運算符:使用new運算符的表達式,首先以其類型說明符的大小作為第一個參數調用new運算符,如果成功完成后,它將自動初始化或構造對象(如果需要)。 最后,該表達式將計算為指向適當類型的指針。
注意最后一句話。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.