代码之家  ›  专栏  ›  技术社区  ›  hiddensunset4

动态数组初始化

c++
  •  1
  • hiddensunset4  · 技术社区  · 14 年前

    我想创建一个foo的动态数组,其中项的数量为x。参数y和z将传递给foo项的构造函数。我希望做一些类似的事情:

    Foo* bar = new Foo(y, z)[x];
    

     error: expected `;' before '[' token
    

    所以在和一个有经验的朋友谈过之后,他给了我这个,他承认这是一个懒惰的方式,但它是有效的。我在想,有没有更好的/合适的方法?

    Foo* bar = (Foo*) new int[x];
    for (int i = 0; i < x; i++) {
        bar[i] = Foo(y, z);
    }
    
    4 回复  |  直到 12 年前
        1
  •  11
  •   GManNickG    14 年前

    “我想做一个动态数组”所以使用 std::vector ,它的存在是有原因的。

    std::vector<foo> bar(x, foo(y, z));
    

    x 元素初始化为 foo(y, z)


    上述情况使 副本 第二个参数, 次。如果你想的话 生成 的值 vector generate_n :

    std::vector<double> weights;
    std::generate_n(std::back_inserter(weights), x, ...);
    

    ... 如果要调用函数或函子,则返回一个值。一般来说,你做一个函子:

    struct generate_weight
    {
        double operator()() const
        {
            return random(1e-3);
        }
    };
    

    给:

    std::generate_n(std::back_inserter(weights), x, generate_weight());
    

    如果编译器支持C++ 0x,那么可以利用lambda。这些方法都是相同的,除了它们保持代码简洁和本地化:

    std::generate_n(std::back_inserter(weights), x,
                    [](){ return random(1e-3); } );
    
        2
  •  1
  •   Lima Beans    14 年前

    如果要将每个元素初始化为相同的值,请按照GMan上面的建议执行:

    std::vector<foo> bar(x, foo(y, z));
    

    如果希望每个foo都有一个唯一的值,则需要在循环中对其进行初始化。一个简单的例子是:

    std::vector<foo> bar;
    
        for (int i = 0; i < x; ++i)
        {
            // initialize X foos with different values for each foo.
            bar.push_back(foo(i, random(i)));
        }
    
        3
  •  1
  •   AnT stands with Russia    14 年前

    首先,您可以在数组新表达式中使用的唯一初始值设定项是 () . 所以,如果你想使用新的表达式,这些是你唯一的选择

    foo *bar = new foo[x];   // 1. no initializer
    foo *bar = new foo[x](); // 2. `()` initializer
    

    foo 如果定义为,这两种行为可能相同,也可能不同。

    其次,由于不能传递构造函数参数 (y,z) 在新表达式中,必须默认构造数组(如上所示),然后使用赋值为数组元素指定值。为了这个你的 必须是默认的可构造的和可复制的。代码看起来很像你的“有经验的朋友”建议的那样,但是使用了适当的类型(而不是 int ). 你现在所拥有的是无用的(那是从哪里来的

    foo *bar = new foo[x];
    for (int i = 0; i < x; i++)
      bar[i] = foo(y,z);
    

    第三,就你的具体情况而言 std::vector 会以更优雅的方式做同样的事情。

        4
  •  0
  •   Charles Beattie    14 年前

    如果你坚持不使用性病,至少要正确使用。这是不安全的,有很大的调整问题。

    size_t x = 10;
    foo * bar= static_cast<foo*> (::operator new ( sizeof(foo)* x));
    for (size_t i=0; i<x; ++i)
    {
        new (&bar[i]) foo (1,1); 
    }
    
    ::operator delete (bar);