STL——vector以及emplace_back分析

在这里插入图片描述
1、这里需要注意凡是连续空间的容器都提供operator[],[]是为了数组操作
2、back()应该是*(end()-1)!!!
3、vector的大小为12;

在这里插入图片描述
在这里插入图片描述
vector的迭代器为指针
在这里插入图片描述

1. emplace_back

1. 相比push_back,只需要构造,不需要拷贝构造或者move
2. 由于其构造函数的特殊性,支持传入多个参数,通过默认构造函数生成右值,并完成构造
3. 与push_back的区别在于,构造应在容器中完成,而非在容器外完成,所以不需要move或者拷贝构造!

vector< A> vaa;
vaa.reserve(5);
A aaaa(1);
vaa.push_back(1);//传递1,隐形构造A(1),为右值,走2
vaa.push_back(aaaa);//为左值,走1
C.push_back(C3(1,"ss")); 这两个等价
C.emplace_back(3,"kk"); 这两个等价

  1. 注意,这里的push_back(value_type&& _x),为右值引用,因为push_back是在class里的,value_type是确定的!同时注意const T&& 这里也是右值引用
  2. 注意emplace_back代码,这里模板嵌套,实则是万能引用,与vector的推导没有关系!
template<class T, class Allocator = allocator<T>>
class vector
{
public:
	template<class... Args>
	void emplace_back(Args... args);

在这里插入图片描述
在这里插入图片描述
==注意点第二次 Copy Constructor应该是 vector在扩容产生的复制,可以在开始先把 vector reserve一个较大的值 ==

class C3{
public:
    C3(){}
    C3(int ii,string ss):i(ii),s(ss){cout << " constructor " << endl;}
    C3(const C3& c):i(c.i+100),s(c.s + "hhhhhhhhhhh"){cout << " copy constructor " << endl;}
int i;
    string s;
};

main 函数:
        vector <C3> vC;
        vC.push_back(C3(1,"ss"));
        cout << vC[0].i << endl;
        cout << endl;
        vC.emplace_back(3,"kk");
        cout << vC[1].i << " " << vC[0].i << endl;


输出:

 constructor 
 copy constructor 
101

 constructor 
 copy constructor 
3 201

2. begin函数

函数原型:

iterator begin();

const_iterator begin();

功能:

返回一个当前vector容器中起始元素的迭代器。

3. end函数

函数原型:

iterator end();

const_iterator end();

功能:

返回一个当前vector容器中末尾元素的迭代器。

4.front函数

函数原型:

reference front();

const_reference front();

功能:

返回当前vector容器中起始元素的引用。

5.back函数

函数原型:

reference back();

const_reference back();

功能:

返回当前vector容器中末尾元素的引用。

6.reserve和resize

  1. vector 的reserve增加了vector的capacity,但是它的size没有改变!
  2. resize改变了vector的capacity同时也增加了它的size!
    原因如下:
    reserve是容器预留空间,但在空间内不真正创建元素对象,所以在没有添加新的对象之前,不能引用容器内的元素。加入新的元素时,要调用push_back()/insert()函数。
    resize是改变容器的大小,且在创建对象,因此,调用这个函数之后,就可以引用容器内的对象了,因此当加入新的元素时,用operator[]操作符,或者用迭代器来引用元素对象。此时再调用push_back()函数,是加在这个新的空间后面的。
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;  

不管是调用resize还是reserve,二者对容器原有的元素都没有影响。

猜你喜欢

转载自blog.csdn.net/weixin_44537992/article/details/104158547