C++:线上课程2

C++:线上课程2,第1张

文章目录

  • 一、Vector

    • 1. vector 源码剖析与仿写
    • 2. 容器初始化
    • 3. 元素访问
    • 4. 迭代器
    • 5. 容量
    • 6. 修改器
    • 7. 元素容量和元素个数
    • 8. 对元素进行访问的几种方式
    • 10. vector扩容函数
    • 11. 原位构造函数



一、Vector 1. vector 源码剖析与仿写

vector简介:

1.vector是表示可以改变大小的数组的序列容器。


// SegList

2.vector与数组一样,元素使用连续的存储空间,就可以使用常规指针,指向其元素,使用偏移量来访问存储空间中的元素。


3.vector与数组不同的是,vector的大小可以动态变化,容器会自动扩容存储空间


4.vector使用一个动态分配的连续存储空间来存储元素。


在插入新元素时存储空间可能需要重新分配,以便增大大小,这意味着分配一个新存储空间要将所有元素移动到其中。


就处理时间而言,这是一项相对昂贵的任务,因此,向量不会在每次向容器添加元素时重新分配。


5.vector容器可以分配一些额外的存储空间以适应可能的增长,因此容器的实际容量可能大于严格需要的存储容量(即容器的大小)。


6.vector与array相比,向量消耗更多的内存,以换取管理存储和以高效方式动态增长的能力。


7.与其他动态序列容器(deques、 list和forward_list)相比,vectors可以非常高效地访问其元素(就像数组一样),并相对高效地从其末尾添加或删除元素。


对于在结尾以外的位置插入或删除元素的 *** 作,其性能较差。


学习STL的方法,首先会使用,其次掌握原理,再次可以扩展(二次开发)。


2. 容器初始化
#include
#include
using namespace std;

int main()
{ 
	//vector初始化
	vector<int> ar1;
	vector<int> ar2 = { 12,23,34,45,56,67,78,89,90,100 };
	vector<int> ar3(10, 23); //开辟10个空间,每个空间的元素都是23
	vector<int> ar4({ 12,23,34,45,56,67,78,89,90,100 }); //把列表加入

	vector<int> ar5(ar1); //用一个对象初始化另一个对象
	vector<int> ar6(std::move(ar2)); //移动构造

	return 0;
}
3. 元素访问
at访问指定的元素,同时进行越界检查
operator[]返问指定的元素
front访问第一个元素
back访问最后一个元素
data访问指向内存中数组的第一个元素的指针
4. 迭代器
begin / cbegin返回指向起始的迭代器
end / cend返回指向末尾的迭代器
rbegin / crbegin返回指向起始的逆向迭代器
rend /crend返回指向末尾的逆向迭代器
5. 容量
empty检查容器是否为空
size返回容纳的元素数
max_size返回可容纳的最大元素数
reserve预留存储空间
capacity返回当前存储空间能够容纳的元素数
shrink_to_fit通过释放未使用的内存减少内存的使用
6. 修改器
clear清除内容
insert插入元素
emplace原位构造元素
erase擦除元素
push_back将元素添加到容器末尾
emplace_back在容器末尾就地构造元素
pop_back移除末元素
resize改变容器中可存储元素的个数
swap交换内容
7. 元素容量和元素个数

size = last - first;

cap = end - first;

8. 对元素进行访问的几种方式
int main()
{
	vector<Object> objvec = { Object(10),Object(20),Object(30),Object(40) };
	cout << objvec.size() << endl;
	cout << objvec.capacity() << endl;

	for (int i = 0; i < objvec.size(); ++i)
	{
		cout << objvec[i].Value() << endl;//下标对元素进行访问
	}
	for (int i = 0; i < objvec.capacity; ++i)
	{
		cout << objvec.at(i).Value() << endl;//at函数对元素进行访问
	}
	//普通迭代器对元素进行访问
	vector<Object>::iterator it = objvec.begin();
	for (; it != objvec.end(); ++it)
	{
		cout << it->Value << " " << endl;
		it->Value() += 100;
		cout << " " << (*it).Value() << endl;
	}
	//常性迭代器对元素进行访问
	for (; cit != objvec.end(); ++cit)
	{
		cout << cit->Value() << endl;
		cout << (*cit).Value() << endl;
	}

	return 0;
}
10. vector扩容函数

void reserve( size_type new_cap ); (C++20前)

constexpr void reserve( size_type new_cap ); (C++20起)

增加vector的容量到大于或等于new_cap的值。


若new_cap大于当前的capacity(),则分配新存储,否则该方法不reserve()不更改vector的size。



若new_cap大于capacity(),则所有迭代器,包含尾后迭代器和所有到元素的引用都被非法化。


否则,没有迭代器或引化。


初始化

template<class T>
class SeqList
{
	T* data;
	int maxsize;
	int cursize;
public:
	SeqList(int sz = 10) :data(T new[sz]), maxsize(sz), cuisize(sz) {}
	SeqList(std::initializer_list<T> init)
	{
		maxsize = init.size();
		cursize = maxsize;
		data = (T*)malloc(sizeof(T) * maxsize);
	}
};
int main()
{
	SeqList<int> seqlist{ 12,23,34,45,56 };//可以用此方式进行初始化
}
11. 原位构造函数

原位构造函数示例讲解(直接在定位中写)

int main()
{
	vector<Object> objvec;
	objvec.reserve(10);
	objvec = { Object(10),Object(20) ,Object(30) ,Object(40) };
	cout << objvec.size() << endl;
	cout << objvec.capacity() << endl;

	objvec.emplace_back(100);
}

原为构造函数重写

将构建对象的地址传递,用定位New直接
调动构造函数构建对象

class Object
{
private:
	int value;
public:
	Object(int x = 0) 
		:value(x)
	{
		cout << " Object " << endl;
	}
	Object(int x, int y)
		:value(x + y)
	{
		cout << " Object " << endl;

	}
	Object(const Object& obj)
		:value(obj.value)
	{
		cout << " Object& " << endl;
	}
	Object(Object&& obj)
		:value(obj.value)
	{
		cout << " move Object&& " << endl;
	}
	Object& operator=(const Object& obj)
	{
		value = obj.value;
		cout << " operator = " << endl;
		return *this;
	}
	Object& operator=(Object&& obj)
	{
		value = obj.value;
		cout << " move operator = " << endl;
		return *this;
	}
	~Object()
	{
		cout << " ~Object " << endl;
	}

	int& Value()
	{
		return value;
	}
	const int& Value() const
	{
		return value;
	}
};

template<class T,class...Arg>
void Make(T* p, Arg... arg)
{
	new(p) T(arg...);// 定位new
}
int main()
{
	Object* p = (Object*)malloc(sizeof(Object));

	Make(p, 12);
	return 0;
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/585376.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-12
下一篇 2022-04-12

发表评论

登录后才能评论

评论列表(0条)

保存