C++两组容器操作的区别:reserve()和resize()、emplace_back()和push_back()

描述

C++执行容器(vector,map等)操作时,总有一些需求,比如说设置容器大小啊,增加元素啊。

这里介绍两组写法的区别,设置容器大小的reserve()和resize()、添加元素的emplace_back()和push_back()

1. reserve()和resize()

这个比较简单。

  • reserve()增加了vector的capacity,但是它的size没有改变
  • resize()改变了vector的capacity,同时也增加了它的size!

原因如下:

reserve是容器预留空间,但在空间内不真正创建元素对象,所以在没有添加新的对象之前,不能引用容器内的元素。加入新的元素时,要调用push_back()/insert()函数。

resize是改变容器的大小,且在创建对象,因此,调用这个函数之后,就可以引用容器内的对象了,因此当加入新的元素时,用operator[]操作符,或者用迭代器来引用元素对象。此时再调用push_back()函数,是加在这个新的空间后面的。

最后面一节是resize和reserve的一些例子,这里我还是给出我的总结

当我们写代码时
当我们已知这个向量的大小时

vector<int> vect;
vect.resize(100); // 比如你已知大小为100
for (int i = 0 ; i < 100 ; i++)
{
	vect[i] = i;  // 建议你一个一个赋值
}

当我们不确定这个向量要存多少变量时

vector<int> vect;
vect.push_back(1); // 你可以一直push_back
cout<<vect.size()<<endl; // 向量的实际大小

2. emplace_back()和push_back()

总结,一般情况下,请你使用push_back(),不要使用emplace_back()

使用emplace_back()的唯一好处就是,你可以不创建对象,就可以向容器里增加一个对象。一般来说,emplace_back()函数要比push_back()函数要快一倍。

push_back() 在底层实现时,会优先选择调用移动构造函数,如果没有才会调用拷贝构造函数。显然完成同样的操作,push_back() 的底层实现过程比 emplace_back() 更繁琐,换句话说,emplace_back() 的执行效率比 push_back() 高。

举例子

#include   
#include   
#include   
 
struct President  
{  
    std::string name;  
    std::string country;  
    int year;  
 
    President(std::string p_name, std::string p_country, int p_year)  
        : name(std::move(p_name)), country(std::move(p_country)), year(p_year)  
    {  
        std::cout << "I am being constructed.\n";  
    }
    President(const President& other)
        : name(std::move(other.name)), country(std::move(other.country)), year(other.year)
    {
        std::cout << "I am being copy constructed.\n";
    }
    President(President&& other)  
        : name(std::move(other.name)), country(std::move(other.country)), year(other.year)  
    {  
        std::cout << "I am being moved.\n";  
    }  
    President& operator=(const President& other);  
};  
 
int main()  
{  
    std::vector<President> elections;  
    std::cout << "emplace_back:\n";  
    elections.emplace_back("Nelson Mandela", "South Africa", 1994); // 可以不创建类 
 
    std::vector<President> reElections;  
    std::cout << "\npush_back:\n";  
    reElections.push_back(President("Franklin Delano Roosevelt", "the USA", 1936));  
}

程序运行结果为

emplace_back:
I am being constructed.

push_back:
I am being constructed.
I am being moved.

例子

vector<int> myVec;
myVec.reserve( 100 );     // 新元素还没有构造, 此时不能用[]访问元素
for (int i = 0; i < 100; i++ )
{ 
     myVec.push_back( i ); //新元素这时才构造
}
myVec.resize( 102 );      // 用元素的默认构造函数构造了两个新的元素
myVec[100] = 1;           //直接操作新元素
myVec[101] = 2;  
vector<int> vect;
vect.push_back(1);
vect.push_back(2);
vect.push_back(3);
vect.push_back(4);
vect.reserve(100);
cout<<vect.size()<<endl;  //size为4
cout<<vect.capacity()<<endl;  //capacity为100
vector<int> vect;    
vect.push_back(1);
vect.push_back(2);
vect.push_back(3);
vect.push_back(4);
vect.resize(100);    
cout<<vect.size()<<endl;  //size为100
cout<<vect.capacity()<<endl;  //capacity为100
vector<int> vect;        
vect.resize(100);    //分配100个空间
vect.push_back(1);
vect.push_back(2);
vect.push_back(3);
vect.push_back(4);
std::cout<<vect.size()<<std::endl; //现在size为104, 
std::cout<<vect.capacity()<<std::endl; //但是capacity不一定是104,vector会自增长预留空间的.
std::cout<<vect[0]<<std::endl; // vect[0]~vect[99]是0
std::cout<<vect[100]<<std::endl; // 1
std::cout<<vect[101]<<std::endl; // 2
std::cout<<vect[102]<<std::endl; // 3
std::cout<<vect[103]<<std::endl; // 4

你可能感兴趣的:(C++)