首先,我想向大家保证,我出于好奇而问这个问题。我的意思是,不要告诉我,如果我需要这个,那么我的设计有问题,因为我不需要在实际代码中。希望我说服你:)现在问题:
对于大多数类型T我们可以写
T* p = new T;
现在如果T是数组类型怎么办?
int (*p)[3] = new ???; //pointer to array of 3 = new ???
我试过了:
typedef int arr[3];
arr* p = new arr;
但这不起作用。
是否有任何有效的语法,或者在C ++中是不可能的。如果不可能,为什么呢?感谢
编辑 :我猜我不够清楚。我希望能够在这种情况下使用它:
void f(int(&)[3]);
int (*p)[3] = new ???;
f(*p);
答案 0 :(得分:11)
要从new
获取指向数组的指针,您必须动态分配一个二维数组:
int (*p)[3] = new int[1][3];
答案 1 :(得分:10)
你不能这样做的原因是new int[3]
已经准确地分配了你想要的类型int[3]
的对象。只是new-expression 返回的内容是指向其第一个元素的指针。 5.3.4 / 1:
如果实体是非数组对象, new-expression返回一个指针 到创建的对象。如果是的话 数组,new-expression返回一个 指向初始元素的指针 阵列。
返回指向第一个元素的指针是允许3
在运行时被识别的原因,所以我想通过提前知道它,你已经超过了你没有使用的灵活性。
我想解决这个问题的方法是将reinterpret_cast重新解释为你想要的指针类型(不一定是可移植的),或者分配一个包含int[3]
的结构(并使用指向其数据成员的指针)。
[编辑:呃,是的,或FredOverflow的想法,既没有劣势,但需要使用delete[]
代替delete
。]
我想道德是,如果你编写的模板天真地用T
分配一些未知类型new
,那么当有人将数组类型作为T
传递时,模板将不起作用。你将它分配给错误的指针类型,如果你修复它(可能是auto
),你将错误地删除它。
编辑回答j_kubik的问题:
这是区分数组和非数组类型的一种方法。如果您编写这样的函数,它返回一个包含指针的对象并能够正确删除它,那么您对任何类型T都有一个通用的新/删除。
#include <iostream>
template <typename T>
void make_thing_helper(T *) {
std::cout << "plain version\n";
}
template <typename T, int N>
void make_thing_helper(T (*)[N]) {
std::cout << "array version\n";
}
template <typename T>
void make_thing() {
make_thing_helper((T*)0);
}
int main() {
typedef int T1;
typedef int T2[3];
make_thing<T1>();
make_thing<T2>();
}
答案 2 :(得分:2)
你总是可以使用boost :: array,它将在C ++ 0x中。 否则,任何解决方案充其量都是尴尬的:数组是 用C语言打破,C ++在这方面保持了与C的兼容性 尊重。 Fred Overflow提供了一个解决方案;更容易(但是 语法噪音)将数组包装在一个结构中: struct A {int arr [3]; }; 并分配和操纵它。
答案 3 :(得分:-2)
你刚才
int *p = new unsigned int [3]
然后,您可以使用*p
作为指针或数组,即*(p+1) or p[1]