动态数组的初始化列表?

时间:2011-08-19 16:56:47

标签: c++ arrays dynamic

可以为静态数组的定义提供初始化列表。例如:

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支持其中一些,但我不能使用它。 现在我可以使用这样的结构。也许有人知道一招......

最佳!

5 个答案:

答案 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;
}

显然,矢量是执行此操作的首选方式。