代码改变世界

STL vector<typename>成员函数:swap(vector<typename> &vt), size(), capacity(), reserve(), resize(), clear()的那些事

2013-10-20 01:04  Ross Wang  阅读(807)  评论(0编辑  收藏  举报

经常用到但是不清楚具体区别和联系很容易误用,各公司面试题的重点照顾区域,所以有必要放在一起总结一下。

1. 执行clear()方法后是否释放了container的内存?

clear()方法执行后,container不保证内存的释放,虽然这个时候container的size肯定会变为0。

C++ 手册上这样说明的:

A reallocation is not guaranteed to happen, and the vector capacity is not guaranteed to change due to calling this function. 

如果需要明确地要求内存的释放,可以采用下面的方法:

vector<T>().swap(vt);

或者:

vt.swap(vector<T>());

这就引出了下一个问题。

2. 下面的代码代表什么意思?

vector<int> vi;
...//插入一些数据
vector<int>(vi).swap(vi);

定义一个固定长度的vector container之后,插入一些数据,做一些事情,如果以后这个container里面的元素变少了,但是长度没有变,这就造成了内存的浪费,比如使用vector<int> vi(1024,20);这种方式。

能否使用vi.resize(vi.size());是否可以减少内存空间呢,不可以,因为vector container的内存会有预分配,也就是capacity()所表示的值。

vector<int>(vi).swap(vi)可以,因为vector<int>(vi)其实就是调用了vector<int>的构造函数生成了一个临时对象,用vi来初始化,然后用其来和vi进行交换,初始化的时候根据vi的元素个数,内存是刚好足够的,这样交换后就使vi的内存刚好和它的size匹配。

这种用法是本身作为右值的vector<int>(vi)的一种典型用法,可以看到它表现得很像一个左值,直接调用了本身的成员函数swap。

3. size()和capacity()分别代表什么?

上面已经提到了capacity()方法,它返回编译器给container预分配的空间,随着元素的增加,会自动扩充,不同的编译器有不同的实现。size()返回的就是container里面元素的个数。

下面有个例子大家编译运行一下就可以看到之间的区别。

4. reserve()和resize()分别在什么时候用?

reserve()方法用来扩容,增加预分配空间,resize()用来增加元素个数,resize(const int newSize, const int defaultValue) (以vector<int>为例)接受两个参数,一个个数,一个新加元素的默认值,如果没有提供默认值,那就是用该类型的默认初始值。

5. sizeof 是个函数吗?vector<typename>的对象被sizeof调用后的结果和什么因素有关系?

sizeof有三种语法形式,如下:
1) sizeof( object ); // sizeof( 对象 );
2) sizeof( type_name ); // sizeof( 类型 );
3) sizeof object; // sizeof 对象;

可以看到sizeof不是一个函数,但是可以像函数那样用,本身sizeof是个operator.

sizeof(vi)返回的结果和vi的元素个数无关,但是和编译器类型以及vector<typename>的typename有关。

这里有个例子,感兴趣的可以编译运行一下,加深对这些方法的理解:

#include<vector>
#include<iostream>

using namespace std;

int main()
{
    vector<int> foo;
    for(int i = 0; i<5; ++i)
    {
        foo.push_back(i);
    }
    vector<int> bar;
    for(int i = 0; i<11; ++i)
    {
        bar.push_back(i);
    }
    cout<<"foo.size() = "<<foo.size()<<endl;
    cout<<"bar.size() = "<<bar.size()<<endl;
    cout<<"foo.capacity() = "<<foo.capacity()<<endl;
    cout<<"bar.capacity() = "<<bar.capacity()<<endl;

    foo.swap(bar);
    cout<<"After foo.swap(bar), foo.size() = "<<foo.size()<<endl;
    cout<<"After foo.swap(bar), bar.size() = "<<bar.size()<<endl;
    cout<<"After foo.swap(bar), foo.capacity() = "<<foo.capacity()<<endl;
    cout<<"After foo.swap(bar), bar.capacity() = "<<bar.capacity()<<endl;

    cout << "foo contains:";
    for (unsigned i=0; i<foo.size(); i++)
        cout << ' ' << foo[i];
    cout << '\n';

    cout << "bar contains:";
    for (unsigned i=0; i<bar.size(); i++)
        cout << ' ' << bar[i];
    cout << '\n';

    vector<int>().swap(foo);
    cout<<"After vector<int>().swap(foo), foo.size() = "<<foo.size()<<endl;
    cout<<"After vector<int>().swap(foo), foo.capacity() = "<<foo.capacity()<<endl;
    vector<int>(bar).swap(bar);
    cout<<"After vector<int>(bar).swap(bar), bar.size() = "<<bar.size()<<endl;
    cout<<"After vector<int>(bar).swap(bar), bar.capacity() = "<<bar.capacity()<<endl;

    

    bar.reserve(300);
    cout<<"After bar.reserve(300), bar.size() = "<<bar.size()<<endl;
    cout<<"After bar.reserve(300), bar.capacity() = "<<bar.capacity()<<endl;

    bar.resize(3);
    cout<<"After bar.resize(3), bar.size() = "<<bar.size()<<endl;
    cout<<"After bar.resize(3), bar.capacity() = "<<bar.capacity()<<endl;

    bar.clear();
    cout<<"After bar.clear(), bar.size() = "<<bar.size()<<endl;
    cout<<"After bar.clear(), bar.capacity() = "<<bar.capacity()<<endl;

    getchar();
    return 0;
}

参考资料:

http://www.cplusplus.com/reference/vector/vector/resize/

http://www.cnblogs.com/hello--the-world/archive/2012/05/07/2487372.html

http://blog.csdn.net/csdnji/article/details/169200

如有任何错误或者问题,请大家留言告知,互相讨论提高,谢谢!