什么编译机制投射新运算符的结果?

时间:2016-01-02 16:26:32

标签: c++ new-operator

显然,new运算符返回void*。所以我想知道在调用void*来创建类A*的新实例时,new A()转换为A的机制是什么。

举例说明:

// Example program
#include <iostream>
#include <string>

class A
{
public:
    A() {}    
};

void* createA()
{
    return new A();
}

int main()
{
    A* a1 = new A();
    A* a2 = createA();
    delete a1;
    delete a2;
}

A* a1 = new A()编译好(显然)。

A* a2 = createA()未报告错误:error: invalid conversion from 'void*' to 'A*'(显然也是......)。

实际上,第一个也会从void*转换为A。什么机制或规则允许第一次转换并拒绝第二次转换?

这可能是一个愚蠢的问题......如果是的话,抱歉。

2 个答案:

答案 0 :(得分:2)

这里有一个new expression,它反过来调用operator new(后面是相应的转换),再加上构造函数。

来自cppreference.com

::(optional) new (placement_params)(optional) ( type ) initializer(optional)
  

尝试创建类型的对象,由 type-id 类型表示...

如果您手动调用operator new,例如

,它将无法运行
A* a2 = operator new(sizeof(A));

不会编译。

答案 1 :(得分:1)

这里没有演员。

当编译器看到new表达式时,它首先调用相应的new运算符(取决于new关键字的类型和参数)。返回一个指向原始内存块的指针;这些指针通常被输入为void*,因为它们不引用任何对象。

然后从基类开始执行适当的构造函数(取决于构造函数参数)。执行构造函数的第一步是默认初始化将构造对象的原始内存。这包括初始化对象所需的任何内部元数据,例如,如果它包含虚拟方法,则为vtable。完成后,内存区域包含一个新生对象,因此可以使用正确的类型创建this。然后可以执行构造函数的其余部分(可以隐式或显式地使用this。)

执行完所有构造函数后,new表达式的值为({1}}的(类型)值。