C++ 顺序容器 insert capacity size reserve 操作

C++ 对于顺序容器的操作(vector、string、deque、list、forward_list、array)

这几个容器每个都有其特有的操作:

vector  : 支持push\_back()、pop\_back()、insert()、emplace()、back()、front()、at(n)、emplace_front、emplace\_back()、erase()、V[n]。

list       :  支持push\_back()、pop\_back()、insert()、emplace()、back()    不支持随机访问

array : 所有改变容器大小的操作,这个都不支持,都不支持,都不支持。支持随机访问     at()、back()、front()、a[n]。 

string : 特殊的vector。

push_back(args): 向容器尾部填入值。

pop_back(): 删除容器尾部值。

insert(iter,args): 向容器迭代器所指向的前一个位置插入值。

push_front : 向容器首部插入元素。

随机访问操作: at(n)、V[n]。  两者不同之处在于,如果n超出容器范围,则会引发一个异常,而V[n]不会。

erase(V.begin(),V.end()): 删除容器该范围元素。

emplace、emplace\_front、emplace\_back    与 insert、push\_front、push\_back 作用相同,只是它将参数传递给元素的构造函数。

Example vector operation:

#include<iostream>
#include"myvect.h"


using namespace std;

struct book{
  book(string booknamel,int bookpricel,vector<string> &editionl):bookname(booknamel),bookprice(bookpricel),edition(editionl) {
  }; //构造函数的初始化
  string bookname="python";
  int bookprice=0;
  vector<string> edition;
}; //定义一个book类的对象

int main()
{
        //这个区域就是定义一些容器和用到的变量。
        vector<string> str{"facebook","github","google","intel","IBM"};
        const char *cp_1="Hello World!";
        vector<string> stt{"nn","aa","cc"};
        cout<<"change before:"<<endl;
        string str_5="hahahah";
        vector<book> program;
        for(auto i :str)
        {
          cout<<i<<"\t";

        }
        cout<<endl;

        operate_v(str,cp_1); //函数定义在myvect.h里
        cout<<"change after:"<<endl;
        for(auto i:str)
        {
          cout<<i<<"\t";
        }
        cout<<endl;
        auto ito_1=stt.begin();
        auto ito_2=str.begin();
        auto ito_3=stt.end();
        cout<<"change before:"<<endl;
        for(auto i :str)
        {
          cout<<i<<"\t";

        }
        cout<<endl;
        operate_v(str,ito_2,ito_1+2,ito_3,str_5); //函数定义在myvect.h里
        operate_v(str,cp_1);
        cout<<"change after:"<<endl;
        for(auto i:str)
        {
          cout<<i<<"\t";
        }
        cout<<endl;
        program.emplace_back("c++",100,stt);

        for(auto pro: program)
        {
          cout<<pro.bookname<<"\t";
          cout<<pro.bookprice<<"\t";
          for(auto i:pro.edition)
          {
            cout<<i<<"\t";
          }

        }
        cout<<endl;
        cout<<str.at(2)<<endl;

  return 0;
}

myvect.h

#include<vector>
#include<string>

void operate_v(std::vector<std::string> &str_1,const char *cp);
void operate_v(std::vector<std::string> &str_1,std::vector<std::string>::iterator itr_1,std::vector<std::string>::iterator itr_2,std::string str_2);




void operate_v(std::vector<std::string> &str_1,const char *cp)
{
    str_1.push_back(cp);
}
void operate_v(std::vector<std::string> &str_1,std::vector<std::string>::iterator itr_1,std::vector<std::string>::iterator itr_2,std::vector<std::string>::iterator itr_3,std::string str_2)
{
  str_1.insert(itr_1,str_2);
  str_1.insert(itr_1,{"1233455","223344551"});
  str_1.insert(itr_1,itr_2,itr_3);
}

Run:

xiandonghua@HappyDay:~/c++/c++bin/ch5$ ./tes 
change before:
facebook    github  google  intel   IBM 
change after:
facebook    github  google  intel   IBM Hello World!    
change before:
facebook    github  google  intel   IBM Hello World!    
change after:
cc  1233455 223344551   hahahah facebook    github  google  intel   IBM Hello World!    Hello World!    
c++ 100 nn  aa  cc  
223344551

resize 可以改变容器当前包含当前元素的大小,确切可以访问的单元。就是说它可以缩小我们给容器存储确定值的空间的大小,也可以增大容器当前的大小,并且初始化容器增加之后存储单元的值。这个空间是存储了容器确定的值,不是容器理论上预留的大小。

resize 用法

void resize( size_type count, T value = T() ); (until C++11)
void resize( size_type count ); (1) (since C++11)
void resize( size_type count, const value_type& value ); (2) (since C++11)

example :

void resizes(std::vector<std::string> &V,std::vector<int> &int_V,const size_t n,std::string demo)
{
  V.resize(n,demo);  //传递了两个参数,一个容器大小,一个容器添加的存储单元默认值。
  int_V.resize(n);   //传递了一个参数,只有容器大小,添加存储单元的默认值由系统自动分配,默认为0。
}

  size_t size_v;
        string init_str;
        vector<string> classes{"home","name","id","age","gender"};
        vector<int> age{1,2,3,4,5,6,100};
        cout<<"Please enter you want to change size of the vector:"<<endl;
        cin>>size_v;
        cout<<"Please enter your initialization parameter:"<<endl;
        cin>>init_str;
        resizes(classes,age,size_v,init_str);
        cout<<"string type container:"<<endl;
        for(auto i: classes)
        {

          cout<<i<<"\t";
        }
        cout<<endl;
        cout<<"int type container:"<<endl;
        for(auto i: age)
        {
          cout<<i<<"\t";

        }
        cout<<endl;

RUN:

Please enter you want to change size of the vector:
10
Please enter your initialization parameter:
ni
string type container:
home    name    id  age gender  ni  ni  ni  ni  ni  
int type container:
1   2   3   4   5   6   100 0   0   0   

需要说明的是因为 C++98 标准不支持 auto .所以用到的编译器 应遵循 c++11标准以上。

例如我用的gcc 编译器

xiandonghua@HappyDay:~/c++/srccode/ch5$ g++ tes.cpp -o ../../c++bin/ch5/tes -std=c++11

vector 和 string 在存储的时候是顺序存储,一个值紧挨着下一个值,所以在添加新的元素的时候,可能会因为没有足够后大小的单元去存储,因为容器下一个单元存储别的内容,所以容器会被移动到新创建的容器存储单元当中进而导致指针,引用,迭代器,失效。也会导致速度变慢,因为有一个转移的过程。

那么如何改变容器预留大小呢? ——-> reserve

那么如何查看容器当前预留大小呢? —–> capacity

example :

  cout<<endl<<"age 当前预留大小:  "<<age.capacity()<<"      age 当前容器大小: "         
      <<age.size()<<endl;
  age.reserve(100);
  cout<<"age 改变后预留大小: "<<age.capacity()<<endl;

RUN:

age 当前预留大小:  14      age 当前容器大小: 10
age 改变后预留大小: 100

当使用reserve 改变容器预留大小之后,如果添加元素超过当前设置的大小是可行的,并且capacity 的值发生改变。

capacity 与 size 的区别

显而易见,capacity 是容器预留大小的值,而size是容器目前实际大小的值,在一定范围内size的值与capacity 的值是一样的。

建议:在传递容器大小的值是尽量用size_type 类型。因为int类型是有符号的值,而size_type是无符号类型的值,有时候在比较上或其它用法上会有很多异常行为。


一步一步慢慢学,不怕学的比别人慢,就怕什么也没学。

猜你喜欢

转载自blog.csdn.net/arctic_fox_cn/article/details/80626845
今日推荐