2014-04-14 59 views
4

我正在使用STL库,我的目标是尽量减少数据重新分配情况。 我wndering,确实std :: vector :: assign - 重新分配数据?

的std ::矢量::分配(size_type的N,const的VALUE_TYPE & VAL)

重新分配的数据,如果尺寸不改变或不被实际只分配新值(例如,使用operator =)?

的STL文件在http://www.cplusplus.com/最高审计机关以下(C++ 98):

在填充版(2),新内容是n个元素,每个初始化为val的副本。 如果发生重新分配,则使用内部分配器分配所需的存储空间。

在调用之前在容器中保留的任何元素被销毁并被新构造的元素替换(不发生元素赋值)。 如果 - 且仅当新矢量大小超过当前矢量容量,则会导致分配的存储空间自动重新分配。

短语“没有元素的分配”使这一切都有点混乱。因此,例如,我想要一个类的向量(例如,OpenCV的cv :: Vec3i)。这是否意味着,

  1. cv :: Vec3i的析构函数或构造函数将被调用?
  2. Vec3i内存的直接副本将制作并填充矢量?
  3. 如果我的类在运行时分配内存新的 运算符会发生什么?这个内存不能由普通内存 复制占。这是否意味着,assign()不应该用于这样的对象?

编辑:使用在这种情况下分配的整个目的是在载体中设置所有值设置为0(如果我已经标准::矢量< CV :: Vec3i> v)中。这将会做很多次。 std :: vector本身的大小不会改变。

我想要做的(在较短的办法)什么是以下几点:

for(int i=0; i<v.size(); i++) 
    for(int j=0; j<3; j++) 
    v[i][j] = 0; 

现在我感兴趣的C++ 98

+0

要最小化重新分配,请使用'std :: shared_ptr'。您可以自由地将这些指针从一个容器复制到另一个容器,只是指针本身被复制。使用“只读”对象的方法,它应该解决这个问题。 – Flovdis

+0

它可能意味着“不分配元素......”是新元素是从参数复制构建的,并且没有复制分配发生。因此,如果你有一个明确的存储类型的复制ctor,那么你应该没有问题。 – bstamour

+0

@Flovdis不共享Ctr 11的ptr部分?以为我们在这里讨论的是C++ 98 .. –

回答

0

正如vector::resize方法的情况下,

std::vector::assign(size_type n, const value_type& val) 

将每个元素初始化为val”一副本“。我倾向于使用resize,因为它可以最大限度地减少对象实例/破坏的数量,但它的确如此。如果要尽量减少数据重新分配,请使用resize,但请记住以下几点:

虽然这对于某些数据结构是安全的,但请注意,分配/推送包含指向动态分配数据的类的元素(例如在构造函数中使用new)可能会造成严重破坏。

如果您的课程动态分配数据那么您应该重新实现YourClass::operator=将数据复制到新对象而不是复制指针。

希望它有帮助!

1

我假设你拥有一个充满一些数据的载体,你调用它的分配,这将:

  1. 破坏载体中的所有元素(它们调用析构函数)一样调用清除()
  2. 用n个给定对象的副本填充现在为空的向量,该对象必须有一个拷贝构造函数。

所以,如果你的类分配一些内存,你必须:

  1. 打理这在你的拷贝构造函数
  2. 释放它在析构函数

的重新分配发生时的大小超过分配的内存(矢量容量)。您可以通过调用reserve()来防止这种情况。不过,我认为assign()足够聪明,可以在开始填充向量之前和清除之前分配所需的所有内存(如果这比已经分配的多)。

您可能希望避免因为成本而重新分配,但如果因为对象无法正确处理而试图避免重新分配,那么我强烈建议您不要将它们放入向量中。

+0

+1。关键是“容量”,它至少与旧尺寸一样大。 – MSalters

1

assign语义是在一个相当简单的方法中定义的标准:

空隙分配(SIZE_TYPE N,常量Ť&吨);

效果:

erase(begin(), end());
insert(begin(), n, t);

这意味着第一元素的析构函数将被调用。t的副本是在元素生命周期结束后剩下的原始存储中完成的。

要求是value_typeMoveAssignable(当erase没有擦到容器的末尾,需要将元素移动到开始位置时)。这里使用

insert过载要求value_typeCopyInsertableCopyAssignable.

在任何情况下,载体是无视你的类是如何管理自己的资源。这是你要照顾的。请参阅The Rule of Three.

相关问题