C++ ';新';C+中的运算符和类型定义数组+;

C++ ';新';C+中的运算符和类型定义数组+;,c++,new-operator,typedef,C++,New Operator,Typedef,可能重复: 这是一个理论问题——我想知道为什么C++中的new new []会返回数组的第一个元素,而不是实际数组(或者指向它的指针)。这是我在尝试做类似的事情时想到的 typedef int int4[4]; int4* ni4 = new int4; 虽然我知道为什么这不起作用(虽然一开始还不太清楚;),但它确实让我讨厌那段代码,原则上是A*ptr=newa不编译。我是唯一一个觉得奇怪的人吗?我不太确定我是否理解你的问题。在C++中,与C一样,数组的第一个元素和数组本身的指针之间没有区别

可能重复:

<>这是一个理论问题——我想知道为什么C++中的new new []会返回数组的第一个元素,而不是实际数组(或者指向它的指针)。这是我在尝试做类似的事情时想到的

typedef int int4[4];
int4* ni4 = new int4;

虽然我知道为什么这不起作用(虽然一开始还不太清楚;),但它确实让我讨厌那段代码,原则上是
A*ptr=newa不编译。我是唯一一个觉得奇怪的人吗?

我不太确定我是否理解你的问题。在C++中,与C一样,数组的第一个元素和数组本身的指针之间没有区别。
编辑:正如有人向我指出的那样,这并不是真正正确的-请原谅我的错误,我最近花了太多时间在Java和C上;-)

我觉得奇怪的是使用了
操作符new[]
。代码尝试分配聚合的单个实例,如果聚合是
结构
,这将是合法的

但这是标准在
[expr.new]
节中所要求的行为

但是,有一个非常简单的解决方法:

typedef int int4[4];
int4* ni4 = new int4[1];


这可能是因为以下几点

new (int[N]); // type int(*)[N]
new int[N]; // type int*
new T; /* T* */

只有在中间情况下,<代码> N< /代码>可以是运行时值。然而,规范并未确定此类类型差异。在几乎所有情况下,阵列都需要特殊处理(如中所示,您也不能只是复制它们)。所以你应该准备好专门处理它们。例如,在您的案例中,您还必须使用

delete[]
而不是
delete

只是想说明一下,如果上述情况属实,那么您将需要笨拙的语法

int (*p)[N] = new (int[N]);
(*p)[N-1] = 0;
p[0][N-1] = 0; /* or, equivalently */
p[N-1] = 0; /* but not this, error! */

你首先需要对数组指针进行引用。

它是C的遗留物,实际上是从B继承来的。C++中的本机数组的处理是非常糟糕的,但是它们不能改变。这是C++中许多问题的例子。

是一个键入还是您真正的意思是TyWIFF INT[INT] INT4?埃里克:这是正确的
typedef
语法。但是下一行有一个输入错误,应该是
int4*ni4=newint4带int[4]int4时,我得到错误:在'['token;第二次拼写错误更正Hum不知道我们可以这样键入def,很高兴知道,即使我可能永远不会使用它。当然有区别-它们是不同的类型。
sizeof
将给出不同的结果,您可以编写引用数组(特定大小)的函数,但不是指针。这是错误的,有很大的区别。数组不是指针,但在某些情况下它可以被视为指针。一些区别:1.不同的
sizeof
2.不同的初始化这是非常奇怪的,这是标准行为。也许数组的typedef没有被视为聚合?无论如何,感谢workar的提示ound-它似乎比
int4*ni4=(int4*)好得多我一直在使用的new int4;
。但我的问题仍然存在-为什么标准是这样制定的?我一直认为标准的目标是完整类型的正确性-这似乎有点违规…为什么这会很奇怪?代码试图分配数组,所以
操作符是new[]
被使用。这是标准规定语义的方式。guy显示的代码相当于
new int[4]
,它使用完全相同的对象类型进行分配。@Johannes:In
new int[4]
,数组说明符
[4]
实际上是新表达式语法的一部分,它不是类型的一部分。我通常希望一个新表达式具有可选的noptr new声明符来调用
操作符new[]()
,而一个没有noptr new声明符的表达式调用
操作符new()
。特殊情况数组类型与其他聚合的当前行为使得编写模板代码变得困难。
int[4]
是一个
新类型id
,并指定了一个类型。如果将其用作
新int[4]
,它会告诉系统它应该创建一个
int[4]
类型的对象。当然是
[4]
是由一些语法产物解析的。所有内容都是:)规则完全按照“如果创建了数组对象,请调用‘运算符new[]”,否则使用‘运算符new’”。我也认为你所说的并不是完全不可能的。
new T
当然“看起来不同于”
new U[N]<代码> >,但是从语言的观点来看,当代码< >代码> u[n] < /代码>时,它是相同的。或者只是代码> int *p= new int [n];< /c> >,但是这取决于您需要什么。例如,考虑<代码>(int [n])< /C>作为集合(用<代码>结构{INTf[n];} /Cord> >它将按我的意愿工作)。@j_kubik我不明白你所说的“把(int[N])当作集合”是什么意思
本身是一个聚合。数组是聚合。这就是我的意思-数组是聚合,但它们的语义不同于所谓的结构-如果创建
新的
结构,则返回的指针指向整个结构,而不是其中的一部分。对于数组,我希望返回指向数组的指针。
int (*p)[N] = new (int[N]);
(*p)[N-1] = 0;
p[0][N-1] = 0; /* or, equivalently */
p[N-1] = 0; /* but not this, error! */