C++学习笔记(二十二)

在完成对C语言的学习后,我最近开始了对C++和Java的学习,目前跟着视频学习了一些语法,也跟着敲了一些代码,有了一定的掌握程度。现在将跟着视频做的笔记进行整理。本篇博客是整理C++知识点的第二十二篇博客。

本篇博客设计了一个数组类模板,并介绍了C++的STL。

本系列博客所有C++代码都在Visual Studio 2022环境下编译运行。程序为64位。

目录

数组类模板案例

STL

STL基本概念

STL的组件

STL举例


数组类模板案例

接下来实现一个通用的数组类,其功能有:

可以对内置数据类型以及自定义数据类型的数据进行存储。

将数据存储到堆区。

构造函数传入数组的容量。

提供拷贝构造函数以及operator=防止浅拷贝。

提供尾插法和尾删法对数据进行增加和删除。

可以通过下标访问数组的元素。

可以获取元素个数和数组容量。

#pragma once
#include<iostream>
using namespace std;
template<typename T>
class Array {
private:
	int capacity;
	int size;
	T* arraylist;
public:
	Array(int capacity) {
		this->capacity = capacity;
		size = 0;
		arraylist = new T[capacity];
	}
	Array (const Array &that)
	{
		this->capacity = that.capacity;
		this->size = that.size;
		this->arraylist = new T[this->capacity];
		for (int i = 0; i < this->size; i += 1) {
			arraylist[i] = that.arraylist[i];
		}
	}

	Array& operator=(const Array that)
	{
		if (this->arraylist != NULL){
			delete[] arraylist;
			arraylist = NULL;
		}
		this->capacity = that.capacity;
		this->size = that.size;
		this->arraylist = new T[this->capacity];
		for (int i = 0; i < this->size; i += 1) {
			arraylist[i] = that.arraylist[i];
		}
		return *this;
	}
	void add(T num) {
		if (size == capacity) {
			cout << "It is full" << endl;
			return;
		}
		arraylist[size] = num;
		size += 1;
	}

	void del() {
		if (size == 0) {
			cout << "It is blank" << endl;
			return;
		}
		size -= 1;
	}
	T search(int number) {
		return arraylist[number];
	}

	int getcapacity() {
		return capacity;
	}

	int getsize() {
		return size;
	}

	~Array() {
		if (this->arraylist != NULL) {
			delete[] arraylist;
			arraylist = NULL;
		}
	}
};

这是array.hpp文件中的内容,实现了一个完整的Array类。array类有private权限的int类型成员变量capacity和size,以及T类型的指针arraylist。

有参构造函数传入一个参数,表示数组的容量,赋值给capacity。同时由于是初始化,置size为0。随后为arraylist开辟capacity个T类型空间。

拷贝构造函数将capacity和size的值直接拷贝,而对于arraylist,会新开辟一块空间,大小为被拷贝数组的大小,随后将被拷贝的数组的元素挨个拷贝。

重载=时,将capacity和size的值直接拷贝,而对于arraylist,首先检查指针原来是否为空,如果不空就清空原来的数据,将指针置为NULL。函数会新开辟一块空间,大小为被拷贝数组的大小,随后将被拷贝的数组的元素挨个拷贝。最后将对象返回。

add成员函数进行添加,参数就是要添加的元素。如果size和capacity相等,则代表已满,就提示已满,并返回。否则,将参数赋给下标为size的成员,随后size加一。

del成员函数进行删除,如果size为0就提示已经为空,并返回。否则将size减一。

search成员函数进行查找,参数是要查找的下标,返回此下标对应的元素。

getcapacity和getsize成员函数返回capacity和size的值。

析构函数将数据释放。

#include<iostream>
#include"array.hpp"
using namespace std;
int main(void)
{
	Array<int> arr(10);
	arr.add(5);
	arr.add(10);
	arr.add(12);

	int size = arr.getsize();
	int i;
	for (i = 0; i < size; i += 1) {
		cout << arr.search(i) << "   ";
	}
	arr.add(15);
	arr.add(20);
	arr.add(25);
	arr.del();

	size = arr.getsize();
	cout << "The size is " << size << endl;
	int capacity = arr.getcapacity();
	cout << "The capacity is " << capacity << endl;

	for (i = 0; i < size; i += 1) {
		cout << arr.search(i) << "   ";
	}
	return 0;
}

程序用int类进行了测试。首先设置capacity为10,随后进行测试操作。程序的输出是:

5   10   12   The size is 5
The capacity is 10
5   10   12   15   20

#include<iostream>
#include<string>
#include"array.hpp"
using namespace std;
class person
{
public:
	string name;
	int age;
	person(){}
	person(string name, int age)
	{
		this->name = name;
		this->age = age;
	}
};

int main(void)
{
	Array<person> arr(10);
	person p1("Isabel", 19);
	person p2("Ida", 19);
	person p3("Ivan", 18);
	person p4("Igor", 18);
	person p5("Irene", 17);
	person p6("Irma", 16);
	arr.add(p1);
	arr.add(p2);
	arr.add(p3);
	arr.add(p4);
	arr.add(p5);
	arr.add(p6);

	person p7("Isaac", 16);
	person p8("Iris", 21);
	person p9("Ingrid", 17);
	person p10("Imelda", 9);
	arr.add(p7);
	arr.add(p8);
	arr.add(p9);
	arr.add(p10);

	arr.del();
	arr.del();
	person p11("Isidore", 20);
	person p12("Ike", 14);
	person p13("Ian", 12);
	person p14("Isaias", 8);
	arr.add(p11);
	arr.add(p12);
	int size = arr.getsize();
	cout << "The size is " << size << endl;
	int capacity = arr.getcapacity();
	cout << "The capacity is " << capacity << endl;
	for (int i = 0; i < size; i += 1) {
		person p = arr.search(i);
		cout << "The name is " << p.name << " the age is " << p.age << endl;
	}
	arr.add(p13);
	arr.add(p14);
	return 0;
}

程序创建了一个person类,并让Array类接受person类对象。随后进行了一些测试。

程序的输出是:

The size is 10
The capacity is 10
The name is Isabel the age is 19
The name is Ida the age is 19
The name is Ivan the age is 18
The name is Igor the age is 18
The name is Irene the age is 17
The name is Irma the age is 16
The name is Isaac the age is 16
The name is Iris the age is 21
The name is Isidore the age is 20
The name is Ike the age is 14
It is full
It is full

STL

STL基本概念

软件界希望能有一种可重复利用的东西。C++的面向对象编程和泛型编程提高了复用性。为了建立对数据结构和算法的标准,诞生了STL

STL是标准模板库。广义上分为容器,算法和迭代器。容器和算法通过迭代器进行连接。STL几乎所有代码都是用类模板或函数模板。

STL的组件

STL大体上分为六大组件,容器、算法、迭代器、仿函数、适配器、空间配置器。

容器用于存放数据,STL的容器实现了运用广泛的数据结构,如数组,链表,二叉树,栈,队列。这些容器分为序列式容器关联式容器。序列式容器强调值的排序,每个元素有固定的位置。关联式容器为二叉树结构,各个元素没有严格的顺序关系。

算法是问题的解决办法,计算机的算法是为了解决逻辑或数学问题(有专门讲算法的课)。STL的算法有一些常用的算法。

迭代器是容器和算法的粘合剂。迭代器可以遍历容器所含有的所有元素。每个容器都有自己的迭代器。

仿函数行为类似函数。

适配器用于修饰容器或仿函数或迭代器接口。

空间配置器负责对空间的配置和管理。

STL举例

接下来以容器vector来体现STL的功能。

使用vector需要包含头文件vector

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

void print(int num) {
	cout << num << "   ";
}

int main(void)
{
	vector<int> v;

	v.push_back(10);
	v.push_back(20);
	v.push_back(30);
	v.push_back(40);
	v.push_back(50);
	
	vector<int>::iterator itbegin = v.begin();
	vector<int>::iterator itend = v.end();
	while (itbegin != itend) {
		cout << *itbegin << "   ";
		itbegin += 1;
	}
	cout << endl;

	vector<int>::iterator it;
	for (it = v.begin(); it < v.end(); it+= 1) {
		cout << *it << "   ";
	}
	cout << endl;

	for_each(v.begin(), v.end(), print);
	return 0;
}

程序创建了一个vector容器。定义vector对象时需要指明成员类型,本例为int类型。

push_back函数用于向容器中添加数据,括号内为加入的数据。vector<类型>::iterator是vector类的迭代器。容器对象名.begin()表示开始位置,容器对象名.end()表示结束位置。可以将开始位置赋给迭代器,然后递增,直至等于末尾位置为止,以此来进行循环。for_each算法需要包含algorithm头文件。参数有三个,第一个是开始位置,第二个是结束位置,第三个是函数名。该算法遍历容器,每次都执行传入的函数。本例中print函数输出成员。

程序的输出是:

10   20   30   40   50
10   20   30   40   50
10   20   30   40   50

#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;
class person
{
public:
	string name;
	int age;
	person(string name, int age) {
		this->name = name;
		this->age = age;
	}
};

void print(person p)
{
	cout << "The name is " << p.name << " and the age is " << p.age << endl;
}

int main(void)
{
	vector<person> v;
	person p1("Kevin", 31);
	person p2("Karl", 18);
	person p3("Kenneth", 29);
	person p4("Katrina", 17);
	person p5("Kiko", 33);
	person p6("Keith", 25);
	v.push_back(p1);
	v.push_back(p2);
	v.push_back(p3);
	v.push_back(p4);
	v.push_back(p5);
	v.push_back(p6);
	vector<person>::iterator pebegin = v.begin();
	vector<person>::iterator peend = v.end();
	while (pebegin < peend) {
		cout << "The name is " << pebegin->name << " and the age is " << pebegin->age << endl;
		pebegin += 1;
	}

	vector<person>::iterator pe;
	for (pe = v.begin(); pe < v.end(); pe += 1) {
		cout << "The name is " << pe->name << " and the age is " << pe->age << endl;
	}

	for_each(v.begin(), v.end(), print);
	return 0;
}

程序创建了person类,并用vector容器存储。程序输出以下内容三次:

The name is Kevin and the age is 31
The name is Karl and the age is 18
The name is Kenneth and the age is 29
The name is Katrina and the age is 17
The name is Kiko and the age is 33
The name is Keith and the age is 25

同样,容器可以嵌套容器。

#include<iostream>
#include<vector>
using namespace std;
int main(void)
{
	vector<vector<int>> v;
	vector<int> v1;
	v1.push_back(10);
	v1.push_back(5);
	v1.push_back(15);
	
	vector<int> v2;
	v2.push_back(20);
	v2.push_back(25);
	v2.push_back(50);
	v2.push_back(75);
	v2.push_back(100);
	vector<int> v3;
	v3.push_back(2004);
	v3.push_back(2006);
	v3.push_back(2008);
	v3.push_back(2010);
	v3.push_back(2012);
	v3.push_back(2014);

	v.push_back(v1);
	v.push_back(v2);
	v.push_back(v3);

	vector<vector<int>>::iterator it;
	for (it = v.begin(); it < v.end(); it += 1) {
		vector<int>::iterator ite;
		for (ite = (*it).begin(); ite < (*it).end(); ite += 1) {
			cout << *ite << " ";
		}
		cout << endl;
	}
	return 0;
}

本例中vector里存储存放int类型数据的vector。因此遍历时使用双层循环。*迭代器名的结果的类型就是容器中数据的类型。程序的输出是:

10 5 15
20 25 50 75 100
2004 2006 2008 2010 2012 2014

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值