C++笔记 -- 序列容器vector

向量(vector)
向量(vector)是表示可以改变大小的数组的序列容器。

就像数组一样,向量使用连续的存储位置作为元素,这意味着它们的元素也可以使用常量指向其元素的偏移来访问,并且与数组一样有效。但与数组不同是向量的大小可以动态变化,其存储由容器自动处理。

在内部,向量使用动态分配的数组来存储它们的元素。可能需要重新分配此数组,以便在插入新元素时增大大小,这意味着分配新数组并将所有元素移动到该数组。就处理时间而言,这是相对昂贵的任务,因此,每次将元素添加到容器时,向量都不会重新分配。

相反,矢量容器可以分配一些额外的存储空间以适应可能的增长,因此容器的实际容量可能大于包含其元素所需的存储容量(即,其大小)。库可以实现不同的增长策略以在内存使用和重新分配之间取得平衡,但无论如何,重新分配只应以对数增长的大小间隔发生,以便在向量末尾插入单个元素可以提供摊销的常量时间复杂性(见push_back)。

因此,与数组相比,向量消耗更多内存,以换取管理存储和以有效方式动态增长的能力。

与其他动态序列容器(deques,lists和forward_lists)相比,向量非常有效地访问其元素(就像数组一样)并且相对有效地从其末尾添加或删除元素。对于涉及在末尾以外的位置插入或删除元素的操作,它们的性能比其他位置差,并且与列表和forward_lists相比具有更少的一致的迭代器和引用。


容器属性
1. 序列
序列容器中的元素按严格的线性顺序排序。 各个元素按其顺序访问它们的位置。
2. 动态数组
允许直接访问序列中的任何元素,甚至通过指针算术,并在序列的末尾提供相对快速的元素添加/删除。
3. 分配器
容器使用allocator对象来动态处理其存储需求。


构造函数:
C++11中vector的构造函数有如下:
1. default
explicit vector (const allocator_type& alloc = allocator_type());
2. fill
explicit vector (size_type n);
vector (size_type n, const value_type& val, const allocator_type& alloc = allocator_type());
3. range
template <class InputIterator>
vector (InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type());
4. copy
vector (const vector& x);
vector (const vector& x, const allocator_type& alloc);
5. move
vector (vector&& x);
vector (vector&& x, const allocator_type& alloc);
6. initializer list
vector (initializer_list<value_type> il, const allocator_type& alloc = allocator_type());

// constructing vectors
#include <iostream>
#include <vector>

int main ()
{
	using namespace std;
	// constructors
	vector<int> one;                                // empty vector of ints
	vector<int> two (4, 10);                       // 4 ints with value 10
	vector<int> three (two.begin(), two.end());  // iterating through two
	vector<int> four(three);                       // a copy of three

	// construct from arrays:
	int myarray[] = {1, 2, 3, 4, 5};
	vector<int> five (myarray, myarray + sizeof(myarray) / sizeof(int) );

	cout << "contents of five are:";
	for (vector<int>::iterator it = five.begin(); it != five.end(); ++it)
	{
		cout << ' ' << *it;
	}
	cout << endl;

  return 0;
}

Iterators:
begin
将迭代器返回到开头(公共成员函数)
end
将迭代器返回到end(公共成员函数)
rbegin
返回反向迭代器以反向开始(公共成员函数)
rend
将反向迭代器返回到反向结束(公共成员函数)
cbegin
将const_iterator返回到开头(公共成员函数)C++11
cend
将const_iterator返回到end(公共成员函数)C++11
crbegin
返回const_reverse_iterator以反向开始(公共成员函数)C++11
crend
将const_reverse_iterator返回到反向结束(公共成员函数)C++11

//Iterators:
// vector::begin/end
// vector::rbegin/rend
// vector::cbegin/cend
// vector::crbegin/crend

#include <iostream>
#include <vector>

int main ()
{
	using namespace std;
	vector<int> vec = {1, 2, 3, 4, 5};

	for(auto it=vec.cbegin(); it != vec.cend(); ++it)
	{
		cout << " " << *it;
	}
	cout << endl;

	for(auto it=vec.crbegin(); it != vec.crend(); ++it)
	{
		cout << " " << *it;
	}
	cout << endl;

	
	for(auto it=vec.begin(); it != vec.end(); ++it)
	{
		cout << " " << *it;
		*it *= 2;
	}
	cout << endl;

	for(auto it=vec.rbegin(); it != vec.rend(); ++it)
	{
		cout << " " << *it;
	}
	cout << endl;
	
	return 0;
}

Capacity:
size
返回大小(公共成员函数)
max_size
返回最大大小(公共成员函数)
resize
更改大小(公共成员函数)
capacity
返回已分配存储容量的大小(公共成员函数)
empty
返回vector是否为空(公共成员函数)
reverse
请求更改容量(公共成员函数)
shrink_to_fit
缩小到适合的大小(公共成员函数)C++11

//Capacity:
// vector::capacity
// vector::reserve
// vector::resize
// vector::shrink_to_fit
// vector::size
// vector::empty
#include <iostream>
#include <vector>

int main ()
{
	using namespace std;
	int sz;
	vector<int> foo;
	
	/*
	size_type capacity() const noexcept;
	*/
	sz = foo.capacity();
	cout << "making foo grow:\n";
	for (int i=0; i<100; ++i) 
	{
		foo.push_back(i);
		if (sz!=foo.capacity()) 
		{
			sz = foo.capacity();
			cout << "i=" << i << ", capacity changed: " << sz << endl;
    	}
	}

	vector<int> vec(100);
	cout << "1. capacity of vec: " << vec.capacity() << endl;
	/*
	void resize (size_type n);
	void resize (size_type n, const value_type& val);
	*/
	vec.resize(10);
	cout << "2. capacity of vec: " << vec.capacity() << endl;
	//size_type size() const noexcept;
	cout << "2. size of vec: " << vec.size() << endl;
	//size_type max_size() const noexcept;
	cout << "2. max_size of vec: " << vec.max_size() << endl; 
	
	//void shrink_to_fit();
	vec.shrink_to_fit();
	cout << "3. capacity of vec: " << vec.capacity() << endl;

	//void reserve (size_type n);
	vec.reserve(300);
	cout << "4. capacity of vec: " << vec.capacity() << endl;

	vec.clear();
	//bool empty() const noexcept;
	if(vec.empty())
	{
		cout << "5. current vec is empty" << endl;
	}
	
	return 0;
}

Element access:
operator[]
访问元素(公共成员函数)
at
访问元素(公共成员函数)
front
访问第一个元素(公共成员函数)
back
访问最后一个元素(公共成员函数)
data
访问数据(公共成员函数)

扫描二维码关注公众号,回复: 4151938 查看本文章
//Element access:
// vector::operator[]
// vector::data
// vector::at
// vector::front
// vector::back
#include <iostream>
#include <vector>

int main ()
{
	using namespace std;
	vector<int> vec(5);

	//vector::operator[]
	for(int i=0; i<vec.size(); ++i)
	{
		vec[i] = i;
	}
	for(auto& x: vec)
	{
		cout << " " << x;
	}
	cout << endl;

	//vector::data
	int* p = vec.data();
	*p = 10;
	++p;
	*p = 20;
	++p;
	*p = 30;
	p[2] = 40; //means vec[2+2] = 40;

	//vector::at
	for(int i=0; i<vec.size(); ++i)
	{
		cout << ' ' << vec.at(i);
	}
	cout << endl;

	vec.push_back(100);
	//vector::front , vector::back
	vec.front() = vec.back() - 50;
	cout << "vec.front()=" << vec.front() << endl;
	cout << "vec.back()=" << vec.back() << endl;

	return 0;
}

Modifiers:
assign
分配矢量内容(公共成员函数)
push_back
在最后添加元素(公共成员函数)
pop_back
删除最后一个元素(公共成员函数)
insert
插入元素(公共成员函数)
erase
擦除元素(公共成员函数)
swap
交换内容(公共成员函数)
clear
清除内容(公共成员函数)
emplace
构造并插入元素(公共成员函数) C++11
emplace_back
构造并在最后插入元素(公共成员函数)C++11

//Modifiers:
// vector::assign
// vector::push_back
// vector::pop_back
// vector::emplace/emplace_back
// vector::erase
// vector::empty
// vector::clear
// vector::swap
// vector::insert
#include <iostream>
#include <vector>

int main ()
{
	using namespace std;
	
	vector<int> one;
	vector<int> two;
		
	//void assign (size_type n, const value_type& val);
	one.assign(10, 100);	// 10 ints with a value of 100
	cout << "Size of one: " << one.size() << endl;
	cout << "Value of one: ";
	for(auto& value: one)
	{
		cout << " " << value;
	}
	cout << endl;

	/*
	template <class InputIterator>
	void assign (InputIterator first, InputIterator last);
	*/
	two.assign(one.begin()+1, one.end()-1);	// the 8 central values of one

	//void push_back (const value_type& val);
	two.push_back(789);
	cout << "Value of two: ";
	for(auto& value: two)
	{
		cout << " " << value;
	}
	cout << endl;

	//void pop_back();
	two.pop_back();
	cout << "Size of two: " << two.size() << endl;

		
	vector<int> vec = {10,20,30};
	/*
	template <class... Args>
	iterator emplace (const_iterator position, Args&&... args);
	*/
	auto it = vec.emplace ( vec.begin()+1, 100 );
	vec.emplace ( it, 200 );
	vec.emplace ( vec.end(), 300 );

	/*
	template <class... Args>
  	void emplace_back (Args&&... args);
	*/
	vec.emplace_back(400);
	vec.emplace_back(500);

	cout << "vec contains:";
	for (auto& x: vec)
	{
		cout << ' ' << x;
	}	
	cout << endl;

	//iterator erase (const_iterator position);
	vec.erase(vec.begin()+2);
	cout << "vec contains:";
	for (auto& x: vec)
	{
		cout << ' ' << x;
	}	
	cout << endl;

	//iterator erase (const_iterator first, const_iterator last);
	vec.erase(vec.begin()+1, vec.end()-2);
	cout << "vec contains:";
	for (auto& x: vec)
	{
		cout << ' ' << x;
	}	
	cout << endl;
	
	//void swap (vector& x);
	vec.swap(two);

	//void clear() noexcept;
	vec.clear();

	//bool empty() const noexcept;
	if(vec.empty())
	{
		//iterator insert (const_iterator position, const value_type& val);
		vec.insert(vec.begin(), 123);
	}
	
	cout << "vec contains:";
	for (auto& x: vec)
	{
		cout << ' ' << x;
	}	
	cout << endl;

	return 0;
}

Allocator:
get_allocator
获取分配器(公共成员函数)

//Allocator:
// vector::get_allocator
//template <class T> class allocator;

#include <iostream>
#include <vector>

int main ()
{
	using namespace std;
	
	vector<int> vec;
	int * p;
	unsigned int i;
	
	// Allocate block of storage for 5 elements:
	p = vec.get_allocator().allocate(5);

	// Construct objects:
	for (i=0; i<5; i++) 
	{
		vec.get_allocator().construct(&p[i], (i+1)*10);
	}

	cout << "allocated array:";
	for (i=0; i<5; i++)
	{
		cout << ' ' << p[i];
	}
	cout << endl;

	// Destroy objects:
	for (i=0; i<5; i++)
	{
		vec.get_allocator().destroy(&p[i]);
	}
	//Release block of storage
	vec.get_allocator().deallocate(p,5);

	return 0;
}

猜你喜欢

转载自blog.csdn.net/sam1437/article/details/84258500