我们假设我有一个班级
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
了。原因是在这种方法中,向量可能希望增长并将所有元素复制到新位置,它不知道我保留了足够的空间。
答案 0 :(得分:2)
我看到三种可能性:
reserve
+ emplace_back
一起使用。您有保证,只要您不超过容量,您的元素就不会被移动。 std::vector
的实现)使用std :: vector&#39; s基于迭代器的构造函数这样的:std::vector<Foo> v(parameters.begin(),parameters.end());
第一种解决方案的优点是更简单,并具有矢量的所有其他好处,如照顾破坏,保持周围的大小等。
第二个解决方案可能更快,因为您不需要执行向量emplace_back
的内务处理,并且即使对于已删除的移动/复制构造函数,如果这对于你,但它会留下几十种错误的可能性
第三种解决方案 - 如果适用 - 是最好的。它也适用于已删除的复制/移动构造函数,不应该有任何性能开销,它为您提供使用标准容器的所有优点。
然而,它依赖于构造函数首先确定范围的大小(例如,通过std::distance
),并且我不确定这是否可以保证任何类型的迭代器(实际上,所有实现都至少这样做)用于随机访问迭代器)。同样在某些情况下,提供适当的迭代器需要编写一些样板代码。