STL vector成员函数详解

1 篇文章 0 订阅

一、 常用简单成员函数

vector::push_back(Type val) //将val添加到向量尾部
vector::pop_back()  //将最后一个元素删除
iterator vector::begin() //返回指向第一个元素的迭代器
iterator vector::end() //返回指向最后一个元素之后的迭代器
vector::clear() //删除向量,并没有释放vector,还是占有capacity个空间,如果要释放空间,可使用 swap(vector<_Ty>()).
vector::at(n)  //等效于vector[n] 返回第n个位置的引用
bool vector::empty()  //向量是否为空
Type vector::front() //返回第一个元素的引用
Type vector::back()  //返回最后一个元素的引用
vector::shrink_to_fit()  //将capacity变为和size一样大
allocator_type vector::get_allocator() //得到分配器

二、vector::size() vector::capacity() vector::max_size()

size_type size()返回的是数组的元素的个数,capacity是数组可容纳元素的个数,如果capacity的大小不够容纳插入的新元素时,vector就会从新找一个更大的连续的空间,并将之前的值赋值到新空间,释放原来的空间,所以在内存中的地址会变,这时原来的迭代器也就会失效。

经过测试,未初始化的数组capacity为0,若初始化了vector的大小则capacity一般和size相等。当capacity不够时,会按照一定的算法扩容(实测:至少扩大原来capacity的一半;如size从100→101,则capacity从100→150;但是如果一次性插入的元素超过原来的一半,则capacity会扩充到刚好,如size从100→200,则capacity从100→200)。
size_type max_size() 返回所能设置的最大capacity.

三、vector::erase()

iterator vector::erase(itrator location);
iterator vector::erase(iterator first, iterator last);

erase(itrator location)删除location位置的元素,并将之后的元素向前移动,迭代器location本身所指的内存中的位置并没有改变,但是所指位置的值变为了下一个位置的元素(因为向前移动了)
erase(iterator first, iterator last) 删除迭代器first到last之间(不包括last)的元素,并将之后的元素移动位置,执行后迭代器location指向内存中的位置没有变,指向的值变成了之前的*last。

四、vector::insert() empalce()

1. insert()

iterator vector::insert(iterator loc,const TYPE &val)
//在loc插入val,返回指向val的迭代器(迭代器指向地址不变),loc原本位置的元素及之后的元素向后移
void vector::insert(iterator loc,size_type num,const TYPE &val)
//在loc插入num个val;loc原本位置的元素及之后的元素向后移
void vector::insert(iterator loc,iterator start,iterator end)
//在loc插入区间[start,end)的所有元素,,loc原本位置的元素及之后的元素向后移

iterator vector::insert(iterator loc,const TYPE &val), 迭代器loc会指向val(因为loc本来位置的元素往后移了一次)

C++11:

iterator insert(const_iterator _Where, const _Ty& _Val) { // insert _Val at _Where
        return emplace(_Where, _Val);
    }
    //函数重载,左值、右值引用 const左值进入此函数
    //这时_Val是一个const引用,传入emplace

iterator insert(const_iterator _Where, _Ty&& _Val) { // insert by moving _Val at _Where
        return emplace(_Where, _STD move(_Val));
    }
    //函数重载,常量、表达式进入此函数
    //_Val是右值引用,为什么还要move?

2. emplace()

iterator emplace(const_iterator _Where, _Valty&&... _Val)
//无重载, ...表示可变参数模板,
decltype(auto) emplace_back(_Valty&&... _Val)

分别表示在iter或最后的位置插入一个元素val,iter原本位置及之后的元素依次向后移。

C++ 11对大部分容器都新加了这两个函数,其中map的使用方式比较特殊;
它们同insert和push_back的区别:最大的作用是避免产生不必要的临时变量,临时变量要申请和释放内存。如下:
(通过测试,insert会构造临时变量Foo,再将Foo拷贝给vector,再释放Foo; C++11的insert会构造临时变量Foo再调用emplace,用拷贝的方式将Foo给vector,再释放原来的Foo。而直接调用emplace在emplace函数内构造Foo,构造时的地址就在vector内,然后用移动赋值的方式将Foo交给vector);另外,vector的insert将所有类型都传入emplace进行处理,但是list的insert只将常量和表达式传入emplace处理,这种区别的原因是什么呢?)
实测:现在的insert(iterator loc,const TYPE &val) 直接调用 emplace

struct Foo {
int vali;
double vald;
    Foo(int n, double x):vali(n),vald(x){};
};

std::vector<Foo> v;
v.emplace(someIterator, 42, 3.1416);        // 没有临时变量产生
v.insert(someIterator, Foo(42, 3.1416));    // 需要产生一个临时变量
v.insert(someIterator, {42, 3.1416});       // 需要产生一个临时变量

五、 vector::assign(iterator start, iterator end)

清除原有的数据,将迭代器[start,end)的内容赋给vector;
若原vector的capacity大于等于新数据的长度,则capacity不变,不然capacity等于新数据的长度。
可以将其他容器的迭代器的内容赋值给vector,但是数据类型最好相同,否则会相应转换

set<int> myset;
myset.insert(1);
myset.insert(3);
myset.insert(2);

vector<int> myvec;
myvec.assign(myset.begin(),myset.end());
从int → float double 则会转换为相应类型
从int → char 则会转换为ASCII码,具体的 33 → '\x33' 表示字符'!'
从char → int ,例:'!' → 33

六、 vector::reserve(int n)

设置vector的capacity的大小(向系统申请连续的内存空间),如果n超过max_size(),则抛出异常。
如果n小于当前的capacity则不起作用。

七、 vector::resize()

void vector::resize(int n)
void vector::resize(int n, Type val)
重新设置vector的大小;
若n小于vector.size(),则删除[vector.begin()+n,vector.end)之间的元素;
若n大于vector.size(),则添加元素,第一个添加T(),第二个添加val。

八、vector::empalce(const iterator iter, Type val)

九、vector::data()

C++11 新加

_Ty* data()
返回指向vector首地址的指针(_Mypair._Myval2._Myfirst),使得可以直接操控vector的底层数据

十、vector::swap(vector &x)

该成员函数会在*this和x之间互相交换被控序列。如果get_allocator()==x.get_allocator(),它将在常数时间内完成交换并且不会抛出任何异常,另外,他还不会导致任何指向这两个被控序列中元素的引用、指针和迭代器无效。否则,它将以与这两个被控序列的元素个数成比例的次数调用元素的构造函数以及为元素赋值。

swap只能同类型之间进行交换。

经测试,当长度、元素类型、维度都不同时,get_allocator()==x.get_allocator()都成立,暂时没有测试出不成立的情况。

swap将所有内容都交换,包括capacity;交换后,原有的迭代器指向的内存地址没有变

十一、迭代器相关

iterator vector::rbegin()  //返回逆迭代器,指向最后一个元素 ,用++则指向倒数第二个元素
iterator vector::rend()  //返回逆迭代器,指向第一个元素的前一个位置

//c++11 新加函数,将指向元素视为const,不可用获得的迭代器修改
iterator vector::cbegin()
iterator vector::cend()
iterator vector::crbegin()
iterator vector::crend();

十二、 _Unchecked_begin()

pointer _Unchecked_begin() noexcept {
        return _Mypair._Myval2._Myfirst;
    }
//返回指向首部的指针

pointer _Unchecked_end() noexcept {
        return _Mypair._Myval2._Mylast;
    }
//返回指向尾部的指针(最后一个元素的后面)

十三、 分配器allocator

_Myval2
     _Myfirst  //指向首地址 vector.begin()返回迭代器所指向的地址
     _Mylast  //指向最后一个元素之后 vector.end()返回迭代器指向的地址
     _Myend  //指向最后分配的内存首地址(capacity的大小)。
  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值