c++ - 如何强制新运算符(operator)根据我的需要解释语句

标签 c++ new-operator

我正在学习 C++。 如果我想声明指向数组的指针,我将使用:

int (*p)[10];

但如果我想声明指针数组,我将使用:

int *(p[10]);

但如果我使用 new 运算符,则没有变量名,例如 p,我必须写成:

x = new int *[10];

问题是:编译器如何确定此语句分配的内存大小,它是指针数组还是指向数组的指针。另外,如何强制编译器根据我的需要解释 int *[10] 的含义?

最佳答案

要声明指向int 的指针数组,您不需要括号:

int* p[10];

会做。要声明一个指向包含 10 个整数的数组的指针,您确实需要括号:

int (*p)[10];

这只是运算符优先级的问题。 []declarator 中的绑定(bind)比 * 更强.因此,如果没有括号,int *p[10]; 将是一个包含十个([10] 首先适用)指向 (* 适用于第二个)intint *(p[10]); 中的括号是多余的。 int (*p)[10]; 另一方面,声明一个指向(* 由于 () 而首先应用)的指针10 个数组([10] 第二个应用)int

new 表达式也不异常(exception)。唯一的区别是您的声明符不包含标识符,因为您没有声明要命名的变量,您只是在拼写一个类型。 new 根据您要求它创建的对象类型计算出它需要多少存储空间。

要简单地声明“指向 int 的十个指针的数组”类型,您可以编写 int* [10]。要声明“指向十个 int 数组的指针”类型,您需要编写 int (*)[10]

但是,new 的上下文中存在一个问题。这个问题是 C++ 中数组类型的边界必须是常量表达式(即编译时常量)。 C++ 类型系统中不存在动态大小的数组。但是,new 的全部意义在于动态创建对象,尤其是动态大小的数组。

要解决这个问题,new 必须避免要求将动态大小的数组命名为类型。目前在 C++ 规范中实现这一点的方法是为 new-expressions 使用完全独立的声明符语法 [expr.new]/1 .那里发生的事情是顶级数组边界被剥离并单独处理。当您编写 new int[n] 时,您创建了一个包含 n 个类型为 int 的对象的数组,其中 n不必是常量表达式。与 new 对其他类型的操作方式相反,如果您要求 new 创建数组类型的对象,new 不会返回指向给定类型的数组,而是指向它创建的数组的第一个元素的指针。因此,即使您创建了一个大小不是常量表达式的数组,new-expression 的结果类型也永远不会是“动态大小数组”,而是始终类型系统中实际存在的东西......

有一个逃生舱口的想法。 new 表达式的语法是 [expr.new]/1

new-expression:
::opt new new-placementopt new-type-id new-initializeropt
::opt new new-placementopt ( type-id ) new-initializeropt

如您所见,new-expression 可以被赋予new-type-id(这是允许创建动态大小数组的单独语法) 或括号中的普通 type-id

因此,实际上可以通过 new 创建一个指向十个 int 数组的指针:

int (**p)[10] = new (int(*)[10]);

关于c++ - 如何强制新运算符(operator)根据我的需要解释语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59130221/

相关文章:

c++ - 创建新结构、插入列表、重新使用指针、在 vector 中返回……是否以及如何删除?

javascript - 我们可以在使用 "new"运算符创建对象时省略括号吗?

java - 接口(interface)实现重写它自己的方法来创建一个自己的对象作为 DEFAULT

c++ - 将递归变成循环

c++17:lambda 到 std::function 转换失败

c++ - 在 C++ 中向数组添加元素

python - 检查 pandas Dataframe 的值是否在两个列表之间。添加一个 boolean 列

c++ - QHttp 示例 qt 4.4.3 的问题

html - 获取html代码时出错

c# - 使用 new 初始化 c# 数组与使用文字初始化