1
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;
}
转变
副本:100
副本:100
尺寸:2 容量:2
转变
副本:17
副本:100
副本:100
100
100
17
0

为什么会这样

copy: 17
copy: 100
copy: 100     

似乎容量是 5 而不是 4,并且在我要推送的元素推入向量后容量增加了,我一定是错的,有人可以告诉我更多细节吗?

4

3 回答 3

3

如果您了解向量的大小和容量之间的区别,您将意识到当需要增加容量时,需要将整个向量移动到内存中的其他位置。

当向量元素从旧向量“移动”到新向量时,就会调用复制构造函数。如果您添加带有一些调试的析构函数,它可能对您更有意义。

还...

for(int i=0; i<vec2.capacity();i++)

...不是一个好主意。您正在访问超出有效矢量数据的末尾。

于 2012-10-09T20:49:17.600 回答
2

就在调用vec2.push_back(17)大小和容量(由您的应用程序打印)之前都是 2。此时 17 被转换为一个A对象,然后将其传递给push_back函数。在内部,std::vector将缓冲区增加到更大的容量(这导致两个副本的A值为 100)并且参数 topush_back被复制到新分配的缓冲区中。在您的实现中,新插入的元素在现有元素之前被复制。

0最后,当您从to迭代时,vec2.capacity()您会导致未定义的行为。您只能合法地从0到迭代向量中的元素vec2.size()。程序的输出表明在您的实现中缓冲区已增长到capacity()==4(打印了 4 个元素)。

于 2012-10-09T20:46:42.313 回答
1

您不应该有使用容量的 for 循环。通常容量会翻倍,这是为了防止在插入新元素时内存被破坏。

如果初始容量为 2,当您添加第 3 个元素时,它将翻倍为 4。当您添加第 5 个元素时,它的新容量将为 8。

于 2012-10-09T20:44:51.953 回答