C与C++中无效*的转换

Conversion of void* in C vs C++

本文关键字:转换 无效 C++      更新时间:2023-10-16

在 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];这样的新表达式中吗?该表达式具有正确的类型,在本例中为 int* ,因此不需要转换。

或者你的意思是内存分配功能operator new()?像malloc()一样,它处理的是原始内存,而不是类型化对象,因此它的返回类型是非类型化void*。它由新表达式在内部使用,该表达式知道正在创建的对象的类型,因此可以在对象完全构造后执行必要的指针转换。

极少数情况下,当你想在自己的代码中使用它时,你必须自己将其转换为正确的类型;但你几乎总是通过新表达式间接使用它,而不必担心这些细节。

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

运算符 new 可以作为常规函数显式调用,但在 C++,new 是具有非常特定行为的运算符:表达式 使用 new 运算符,首先调用函数运算符 new 的大小 其类型说明符作为第一个参数,如果成功,则 然后自动初始化或构造对象(如果需要)。 最后,表达式计算为指向相应 类型。

注意最后一句。