簡體   English   中英

C和C ++中void *的轉換

[英]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繼承了BC (按此順序)。 如果將指針指向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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM