我一直认为T *p = new T;
对所有T
都是有效的C ++ ...直到我尝试
int main()
{
typedef int Array[2];
Array *p = new Array;
}
得到了这个可爱的错误,我无法解读:
error C2440: 'initializing' : cannot convert from 'int *' to 'Array (*)'
有人可以解释为什么这是一个错误吗?
答案 0 :(得分:12)
如果动态分配数组类型,则会得到指向其第一个元素的指针。
§5.3.4[expr.new] 由new-expression创建的实体具有动态存储持续时间。如果该实体是非 数组对象,[...]如果它是一个数组,则new-expression返回一个指向数组初始元素的指针。
因此,由于您正在分配数组类型对象,因此您可以获得int*
:
int *p = new Array;
这与不使用typedef没什么不同:
int *p = new int[2];
这也与您的T *p = new T;
规则不符。也就是说,你绝对不能这样做:
int (*p)[2] = new int[2];
我意识到这种混淆可能是因为new ...[]
是一种与new ...
不同的特殊表达类型,其中new Array
符合后一种情况。我们经常建议可能会说“new[]
应始终与delete[]
匹配”。那条规则有点误导。这里的真正含义是具有数组类型的new
应始终与delete[]
匹配。
答案 1 :(得分:2)
这里的问题是C和C ++中的数组类型语法是乱七八糟的混乱,并且typedef
数组类型为看起来的东西如此混乱不会使它不是那么的。
在表达式中,动态分配数组的结果是指针,而不是数组。类型不同。