4

在 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*呢?如何将其转换为所需的类型?

4

7 回答 7

3

如果你重载operator new,你确实会返回一个void*. 重载operator new基本上是一个简单的分配函数,就像malloc()在 C 中一样。

但是,当您使用operator时new,您所做的不仅仅是调用该函数;例如,您还隐式调用构造函数。new返回完全正确的类型是构造 with和重载operator new函数之间的另一个隐含区别。

C++ 给你一个错误,因为void*它可能指向任何东西。因此,如果您尝试将其分配给特定的事物,那么您所做的假设可能不正确。由于 C++ 是强类型的,因此您必须告诉编译器您的假设并明确说明;这就是类型安全提供的保护机制。C 不是强类型的,开发人员有责任小心。

于 2012-08-08T13:18:00.053 回答
1

编译器对new运算符进行了特殊处理,它从参数中获取类型,new并隐式转换为正确的类型。

如果您创建自己的operator new,则必须返回一个void指针,因为您实际上不知道类型,只知道您需要分配的内存量。

于 2012-08-08T13:17:23.080 回答
1

因为new不是函数,所以它是一个运算符,由编译器专门处理。

于 2012-08-08T13:17:26.840 回答
1

C++ 对指针转换施加了更严格的规则。原因之一可能是因为 C++ 中的指针转换最终可能会导致机器代码,即它不是纯粹的装饰物。

例如类A继承BC(按此顺序)。如果您将指针指向C并将其转换为A- 此结果为(原始)指针移位。

于 2012-08-08T13:18:01.567 回答
1

您需要输入:

  ptr = (int *) p;

new 的结果不是 void *。这取决于您正在创建的对象。如果你这样做

  ptr = new int [2];

不涉及重铸。

于 2012-08-08T13:18:33.017 回答
0

那么,为什么 new 运算符的返回类型是 void* 呢?

你的意思是关键字new,用在新表达式中int * p = new int[42];吗?该表达式具有正确的类型,在这种情况下int*,因此不需要转换。

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

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

于 2012-08-08T13:54:55.010 回答
-1

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

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

注意最后一句话。

于 2012-08-08T13:18:08.520 回答