是否可以在C++中动态创建一个常量大小的数组?
首先,我想让大家放心,因为我好奇地问了这个问题。我的意思是,不要告诉我,如果我需要这个,那么我的设计就会有问题,因为我不需要真正的代码。希望我相信你现在:)的问题:是否可以在C++中动态创建一个常量大小的数组?
对于大多数类型难道我们可以写
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);
你不能这样做的原因是new int[3]
已经准确地分配了你想要的东西,一个int[3]
类型的对象。这就是新表达式返回,是指向其第一个元素的指针。 5.3.4/1:
如果实体是一个非阵列对象, 新表达式返回一个指针 到创建的对象。如果它是一个 数组,则新表达式会返回指向 数组的初始元素的 指针。
返回一个指向第一个元素是什么让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>();
}
两个'新INT [3]'和'新INT [1] [3]'已被释放通过'delete []'。 – fredoverflow 2011-03-17 14:31:13
@FredOverflow:的确,我的意思是“而不是”,非数组类型会发生什么,如果我正在发明Armen想要的魔法不存在的语法,那么要分配一个数组类型的单个对象*好像它是一个非数组类型,那么它会让你通过从'MagicNew'返回的同一个指针'delete'来删除它,所以它看起来像'typedef int arr [3]; arr * p = MagicNew arr; delete p;'我知道他没有在他的问题中指明这一点,也许我错误地认为其他人会以同样的方式创造它 – 2011-03-17 14:36:35
所以总结 - 有没有办法新的删除模板准备好了阵列类型还是简直不可能? – 2011-09-06 06:22:06
你只是做
int *p = new unsigned int [3]
然后可以使用*p
为指针或数组即*(p+1) or p[1]
对不起,但这不是我所能问。在所有 – 2011-03-17 13:55:00
为了得到一个指针从new
到数组,您必须动态分配一个二维数组:
int (*p)[3] = new int[1][3];
嗯......不完全是我期待的,但我的例子肯定会工作...... +1 – 2011-03-17 14:02:12
你总是可以使用boost :: array,它将在C++ 0x中。否则,任何解决方案在最好情况下都会很尴尬:数组是 以C分解,而C++在此方面与C保持相容性。 Fred Overflow提供了一个解决方案;甚至更容易(但 句法噪声)将包装在结构中的数组:结构A {int arr [3]; }; 并分配和操作它。
这将是一个解决方法,而不是解决方案:)而@弗雷德的也是,但至少我的例子与他的工作解决方法。与你的,它不会,是吗? – 2011-03-17 14:08:03
包装是一种解决方法,但boost:array将是我的首选解决方案,用于处理固定大小的数组。所以奇怪,但可能的:空隙F(阵列 & p);阵列 * p值=新的数组; F(* P); – stefaanv 2011-03-17 14:39:07
如果我理解正确的话,你想知道C++是否有一种方法来“推断”数组的大小,而不必在分配中明确指定它? – 2011-03-17 13:56:33
@oakley:不太清楚:我问T是一个数组类型(具有编译时已知维数)时是否使用'T * p = mew T;'语法 – 2011-03-17 13:58:08