矢量预分配无法正常工作

时间:2011-12-11 12:32:12

标签: c++ vector

我在使用以下代码时遇到了一些麻烦:

#include <iostream>
#incldue <vector>

template <typename ElemType>
class A{
private:

  std::vector<ElemType> data;

public:
  A() {};

  A(int capacity) {
    data.reserve(capacity);
  }

  int GetCapacity() {
    return data.capacity();
  }
};

int main() {
  A<int> a;
  a = A<int>(5);
  std::cout << a.GetCapacity() << std::endl; 
} 

输出为0.可能是什么问题?

3 个答案:

答案 0 :(得分:11)

std::vector<T>的复制构造函数和赋值运算符不需要复制向量的容量,只复制元素。因为行a = A<int>(5)间接调用赋值运算符(在创建临时值之后),a中的向量没有容量。

尝试将main的前两行更改为A<int> a(5)并查看结果。

如果您绝对需要将容量从一个实例传输到另一个实例的能力,则需要定义A的赋值和复制构造函数,以复制数据并分配容量。

答案 1 :(得分:2)

因为您尚未实现A的副本分配,所以保留了向量的容量。编译器生成A的副本分配,确保仅复制向量的元素。向量的复制构造函数(和复制赋值)不需要保留源向量对象的容量。它复制元素,保留向量的size

这意味着,如果您将A的副本分配定义为:

 A& operator = (const A & a) 
 {
    data = a.data;
 }

它仍会打印0

您可以通过将副本分配实现为:

来实现所需的行为
 A& operator = (const A & a) 
 {
    data.reserve(a.capacity());
    data.insert(data.end(), a.begin(), a.end());
 }

请注意,.insert()仅复制元素,因为.size()更改了元素,但.capacity保持不变。这就是您需要明确调用.reserve()

的原因

答案 2 :(得分:1)

这是因为您要分配给a,分配只会复制值和容量。

如果你想要具有设定容量的构造,那么。

A<int> a(5);

如果您希望通过作业进行转移,则需要编写自己的作业运算符

A& operator=(const A& a)
{
     if(&a!=this)
     {
         data.assign(a.data);
         data.reserve(a.capacity);

     }
     return *this; 
}