可以为静态数组的定义提供初始化列表。例如:
int main()
{
int int_static[2] = {1,2};
}
动态数组是否可以使用类似的初始化列表?
int main()
{
int* int_ptr = new int[2];
}
这更接近我想要做的事情:
struct foo
{
foo(){}
foo(void * ptr): ptr_(ptr) {}
void * ptr_;
};
int main()
{
foo* foo_ptr = new foo[10];
}
在初始化时,不应该调用默认构造函数,而是调用foo:foo(void *)。
对于动态数组的静态初始化程序列表而言,对于加速器核心的即时编译可能会派上用场,因为加速器核心只有有限的堆栈可用,但同时您构建了具有(加速器编译时间=主机运行时)静态初始化程序列表的对象。
我假设没有(因为这需要编译器生成额外的代码,即将参数的值复制到堆位置)。我认为c ++ 0x支持其中一些,但我不能使用它。 现在我可以使用这样的结构。也许有人知道一招......
最佳!
答案 0 :(得分:14)
在OP发布此问题时,C ++ 11支持可能还不是很流行,这就是为什么接受的答案说这是不可能的。但是,现在应该在所有主要的C ++编译器中支持使用显式初始化列表初始化动态数组。
语法new int[3] {1, 2, 3}
在C ++ 11中标准化。在cppreference.com上引用 new expression 页面:
由new-expression创建的对象根据以下规则初始化:
...
如果 type 是数组类型,则初始化对象数组:
...
如果初始值设定项是括号括起的参数列表,则该数组是聚合初始化的。 (自C ++ 11起)
因此,根据OP的例子,以下在使用C ++ 11或更新版本时完全合法:
foo * foo_array = new foo[2] { nullptr, nullptr };
请注意,通过在初始化列表中提供指针,我们实际上是在哄骗编译器应用foo(void * ptr)
构造函数(而不是默认构造函数),这是所需的行为。
答案 1 :(得分:10)
不,你不能这样做。
我认为C ++不允许这样做,因为允许这样的事情不会为语言添加任何很好的功能。换句话说,如果使用静态初始值设定项初始化它,那么 dynamic 数组的意义是什么?
动态数组的要点是在运行时创建一个大小为N
且已知的数组,具体取决于实际需要。也就是代码
int *p = new int[2];
对我来说没有以下意义:
int *p = new int[N]; //N is known at runtime
如果是这样,那么如何在 static 初始值设定项中提供元素数量,因为在运行时才知道N
?
让我们假设您可以写这个:
int *p = new int[2] {10,20}; //pretend this!
但是你写这个有什么大的优势?没有。它的几乎与相同:
int a[] = {10,20};
真正的优势是当你被允许为N
元素的数组写入时。但问题是这样的:
int *p = new int[N] {10,20, ... /*Oops, no idea how far we can go? N is not known!*/ };
答案 2 :(得分:2)
不,你必须动态创建元素。
或者,您可以使用本地数组并将其元素复制到动态分配的数组中:
int main() {
int _detail[] = { 1, 2 };
int * ptr = new int[2];
std::copy( _detail, _detail+(sizeof detail / sizeof *detail), ptr );
delete [] ptr;
}
在将所有元素设置为0的限制版本中,您可以在new
调用中使用额外的一对括号:
int * ptr = new int[2](); // will value initialize all elements
但你似乎在寻找另一种东西。
答案 3 :(得分:0)
无论如何,初始化数据必须在某处。只需命名即可。
如,
#include <stddef.h>
#include <algorithm> // std::copy
#include <vector>
typedef ptrdiff_t Size;
template< class Type, Size n >
Size countOf( Type (&)[n] ) { return n; }
int main()
{
using namespace std;
static int const initData[] = {1,2};
static Size const n = countOf( initData );
// Initialization of a dynamically allocated array:
int* pArray = new int[n];
copy( initData, initData + n, pArray );
// Initialization of a vector:
vector<int> v( initData, initData + n );
}
编辑:在上面的代码中修改了一个thinko。我赶紧根据要求添加示例。所以我放错了使用来自std::copy
的返回值。
干杯&amp;第h。,
答案 4 :(得分:0)
鉴于你是真正的类比int更复杂,并且由不同的值构造,它很复杂。 如果现有的数组/向量具有默认的正确值,则可以使用迭代器构造向量,或者必须使用新的位置。
//vector
int main()
{
int int_static[2] = {1,2};
std::vector<int> int_dynamic(int_static, int_static+2);
//this is what everyone else is saying. For good reason.
}
//placement new
int function_that_returns_constructed_from_values() {
return rand();
}
int main()
{
int count = 2;
char *char_dynamic = new char[count * sizeof(int)];
int *int_dynamic = char_dynamic;
for(int i=0; i<count; ++i)
new(int_dynamic+i)int(function_that_returns_constructed_from_values());
//stuff
for(int i=0; i<count; ++i)
(int_dynamic+i)->~int(); //obviously not really int
delete []char_dynamic;
}
显然,矢量是执行此操作的首选方式。