如何使用每个对象的单独构造函数参数在C ++中动态分配对象数组?

时间:2017-07-16 11:01:26

标签: c++ arrays c++11 vector constructor

我们假设我有一个班级

Label[] title = new Label[100];
Label[] link = new Label[100];
for (int i = 0; i < 10; i++)
{
    var j = i;
    title[j] = new Label();
    link[j] = new Label();
    title[j].MouseClick += (s, e) => title[j].Text = link[j].Text;
}

我想创建这个类的许多实例。由于我的目标是获得良好的性能,我想立即为所有这些内存分配内存(此时,我知道确切的数字,但仅在运行时)。但是,每个对象都应使用参数向量

中的单个构造函数参数构造
class Foo
{
public:
    Foo (const std::string&);
    virtual ~Foo()=default;
private:
    //some private properties
};

问题:如何实现?

我的第一次尝试是从std::vector<std::string> parameters; 开始,然后是std::vector<Foo>并在循环中使用reserve(parameters.size())。但是我不能使用这种方法,因为我使用指向单个对象的指针,并希望确保它们不会被emplace_back(...)的内部方法移动到内存中的其他位置。为了避免这种情况,我尝试删除Foo的复制构造函数,以确保在编译时不会调用任何可能将对象复制到其他位置的方法,但我不能再使用std::vector了。原因是在这种方法中,向量可能希望增长并将所有元素复制到新位置,它不知道我保留了足够的空间。

1 个答案:

答案 0 :(得分:2)

我看到三种可能性:

  • 将矢量与reserve + emplace_back一起使用。您有保证,只要您不超过容量,您的元素就不会被移动。
  • 使用malloc + placement new。这允许您分配原始内存,然后逐个构造每个元素,例如在一个循环中。
  • 如果您已经有一系列参数来构建对象,就像在示例中一样,您可以(根据您的std::vector的实现)使用std :: vector&#39; s基于迭代器的构造函数这样的:
    std::vector<Foo> v(parameters.begin(),parameters.end());

第一种解决方案的优点是更简单,并具有矢量的所有其他好处,如照顾破坏,保持周围的大小等。 第二个解决方案可能更快,因为您不需要执行向量emplace_back的内务处理,并且即使对于已删除的移动/复制构造函数,如果这对于你,但它会留下几十种错误的可能性

第三种解决方案 - 如果适用 - 是最好的。它也适用于已删除的复制/移动构造函数,不应该有任何性能开销,它为您提供使用标准容器的所有优点。
然而,它依赖于构造函数首先确定范围的大小(例如,通过std::distance),并且我不确定这是否可以保证任何类型的迭代器(实际上,所有实现都至少这样做)用于随机访问迭代器)。同样在某些情况下,提供适当的迭代器需要编写一些样板代码。