class A
{
public:
A():a(0)
{}
A(int x):a(x)
{
cout<<"convert"<<endl;
}
A(const A& rhs):a(rhs.a)
{
cout<<"copy: "<<a<<endl;
}
void print()
{
cout<<a<<endl;
}
void Set(int x)
{
a=x;
}
private:
int a;
};
int main()
{
vector<A>vec2(2,A(100));
cout<<"the size: "<<vec2.size()<<" the capacity: "<<vec2.capacity()<<endl;
vec2.push_back(17);
for(int i=0; i<vec2.capacity();i++)
{
vec2[i].print();
}
cout<<"the size: "<<vec2.size()<<" the capacity: "<<vec2.capacity()<<endl;
}
convert copy: 100 copy: 100 the size: 2 the capacity: 2 convert copy: 17 copy: 100 copy: 100 100 100 17 0
为什么会发生这种情况
copy: 17
copy: 100
copy: 100
似乎容量是5而不是4,并且容量增加后我想要推送到矢量的元素,我一定是错的,有人可以告诉我更多细节吗?
答案 0 :(得分:3)
如果您了解向量的大小和容量之间的差异,您将意识到当需要增加容量时,需要将整个向量移动到内存中的其他位置。
当向量元素从旧向量“移动”到新向量时,会发生对复制构造函数的调用。如果你添加一个带有一些调试的析构函数,那么对你来说可能更有意义。
也...
for(int i=0; i<vec2.capacity();i++)
......不是个好主意。您将访问有效矢量数据的末尾。
答案 1 :(得分:2)
在调用vec2.push_back(17)
之前,大小和容量(由应用程序打印)都是2.此时,17将转换为A
对象,然后传递给{ {1}}功能。在内部,push_back
将缓冲区增大到更大的容量(导致std::vector
的两个副本的值为100),并将A
的参数复制到新分配的缓冲区中。在您的实现中,新插入的元素将在之前复制已存在的元素。
最后,当您从push_back
迭代到0
时,您将导致未定义的行为。您只能合法地迭代向量中从vec2.capacity()
到0
的元素。程序的输出表明,在您的实现中,缓冲区已增长到vec2.size()
(打印了4个元素)。
答案 2 :(得分:1)
你不应该使用容量的for循环。通常,容量将加倍,这是为了防止在插入新元素时出现内存损坏。
如果初始容量为2,则在添加第3个元素时它将加倍为4。当你添加第5个元素时,它的新容量将为8。