显然,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
。什么机制或规则允许第一次转换并拒绝第二次转换?
这可能是一个愚蠢的问题......如果是的话,抱歉。
答案 0 :(得分:2)
这里有一个new
expression,它反过来调用operator new
(后面是相应的转换),再加上构造函数。
::(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}}的(类型)值。