一、什么是封装
C++中有这样一句话,万事万物皆可为对象。
对象指的是某一个类的具体实例化。而类就是将某一类事物的属性和行为进行封装。将类封装起来,就能控制类的属性和行为。
总而言之,封装就是将复杂事物变得能让人轻易就能使用的方法,就像手机、汽车等,都是封装好的成品,只需要掌握操作的接口,就能轻松使用。
二、为什么要封装
一部手机是由各种精密的零件,组件和芯片等组成,由这些精美零件等制成的手机拥有了各种功能。手机就是类,它的属性就是零件,组件,芯片,行为是基于属性衍生出来的、所拥有的功能。对于封装的手机,我们即使不清楚他的底层实现,也可以轻易的上手使用。而封装好的手机,也是对本身的保护,不清楚底层实现原理的我们,看到的如果是各种线路板,既不能方便的使用手机,也无法保证手机的安全使用。
1.数据结构中的栈
在数据结构中有这样一种存储结构----栈
简单了解一下栈:后进先出,只允许在栈顶插入和删除数据
栈的属性,或者说栈是由哪些元素构成,如何用代码描述一个栈
typedef int DataType;
typedef struct Stack
{
DataType* a;//用指针来存放栈中的元素
int top;//记录栈中的元素个数
int capacity;//记录栈空间的大小
}ST;
栈的行为,或者说栈如何使用,拥有什么功能(具体功能实现代码不做显示)
void STInit(ST* pst);
//栈的初始化,因为栈空间本身是由指针指向,指针需要初始化
void STDestory(ST* pst);
//栈的销毁,在实际开辟栈空间时,需要利用malloc函数在堆上开空间,有malloc,就
//必须有free,防止内存泄漏
void STPush(ST* pst,DataType x);
//入栈,在栈顶增添栈数据
void STPop(ST* pst);
//出栈,删除栈顶的数据
DataType STTop(ST* pst);
//返回栈顶元素
bool STEmpty(ST* pst);
//判断栈是否为空
int STSize(ST* pst);
//返回栈的元素个数
2.关于内存泄漏
对某块分配的内存空间使用结束后,确没有释放。举例:
一个垃圾桶,相当于开辟的空间,你需要使用它,所以垃圾桶逐渐被垃圾填满,当向垃圾桶扔了几天垃圾后,你不想再用它了,于是你又买了一个垃圾箱,并且对旧的垃圾桶不做任何处理,任由其占据着一定的空间。
栈的实例化使用:
创建栈时,必须进行初始化,栈使用结束后,必须进行销毁。且是每次创建栈时所进行的必须操作。
3.封装的好处
1.对于某些动态开辟空间的类,无需每次都进行初始化和销毁的操作
2.封装是为了更方便,更好的使用
封装就是将一个成功研发的产品直接让你使用,这个产品的实现可能是无比复杂的,但是作为一个使用者和支配者,我们只需要掌握实现复杂功能的接口即可。例如玩手机和开汽车,手机和汽车的内部构造我们可能不清楚,但这并不妨碍我们熟练的使用他们。
3.保护类中的隐私数据。通过类成员访问限定符,可以限制类中成员的访问权限,以此提供保护。
三、关于string类
string类,也即字符串类,是一个封装好的类。它提供了各式各样的接口函数,只要掌握了这些接口函数,就可以轻松的使用string类,即使我们不清楚底层实现原理。
使用string需要包含的头文件:#include<string>(注意要展开命名空间)
string类的接口函数:
1.成员函数之构造函数
分别是构造函数,析构函数,赋值运算符重载
构造函数的接口函数有很多,如下图
依次来看看这些构造函数的接口函数的具体使用
default(1)
通过调试后,s1的监视窗口如上图
其中描述s1的有size,capacity以及_Buf,分别表示的是字符串s1的字符个数,开辟空间的大小,以及存储的数据
我们可以看到,即使没有对字符串初始化,无参构造函数也会对字符串开辟空间,并放入\0
copy(2) string(const string& str);
函数分析:str接收字符串进行初始化,字符串末尾有‘\0’,如下图
函数解释:接收字符串对s2进行初始化
substring(3) string(Const string& str,size_t pos,size_t len=npos;
函数解释:
拷贝从字符串str下标问pos的位置开始拷贝len个字符,如果str太短(len的长度大于str的长度)或者没有给len传参,会一直拷贝到str的末尾
虽然缺省参数npos的定义中给的值是-1,但因为类型为size_t,实际值如下图
函数使用:如下图
在实际使用中发现,如果没有给len 传递参数并且使用常量字符串进行传参,该构造函数完成的是拷贝str的pos个字符,这是因为编译器识别成了另一个函数:
string (const char* s, size_t n);
该函数也是string类的构造函数,功能是拷贝s指向的n个字符
这是因为常量字符串的类型是const char*,相比const string& str,第一个参数与该函数更加匹配。如下图
如果使用string类的对象初始化,则不会出现错误调用的问题,如下图
from c-str string(4) string(const char* a);
函数解释:拷贝指针a指向的内容如下图
from sequece(5) string (const char* a,size_t n);
函数解释:拷贝指针a指向的size个字符。如下图s5
fill(6) string (size_t n,char c);
函数解释:拷贝n个字符c。如下图
range (7)
template<class InputIterator>
string<InputIterator first,InputIterator last>;
函数解释:拷贝迭代器first到last所指向范围的内容
函数使用:如下图
2.关于迭代器
2.1什么是迭代器
简单来说,我们可以将迭代器当作是指针使用。但实际上,迭代器的类型不同,使用方法也不同。
2.迭代器的分类
输入迭代器:如下图
输出迭代器:
前向迭代器:如下图
双向迭代器:如下图
支持++和--操作所有双向迭代器也是有效的前向迭代器和输入迭代器。
随机迭代器:如下图
2.3常用的迭代器函数
来看看sring类中迭代器的几种玩法
函数解释:begin是string类的公共成员函数之一,它的功能是返回指向的字符串的第一个字符位置的迭代器,如下图
函数解释:返回指向字符串string最后一个字后位置的迭代器iterator
end指向的是字符串的末尾,不包含在string空间内。如下图,先--,才能访问最后一个元素
关于rbegin:指向的位置是反方向的第一个字符,也就是最后一个字符
关于rend:指向的位置是反向结束的位置,也就是第一个字符前
如下图
2.4const修饰的隐含的this指针
const对象只能使用const_iterator类型的迭代器,普通对象既可以使用iterator,也可以使用const_iterator类型的迭代器,但在实际调用时,没有const修饰的迭代器函数调用的优先级要更高,会优先调用
2.5权限放大缩小问题
规定:权限只能缩小或者平移,而不能放大。
如果const对象的权限是只读,不能写
普通对象的权限是可读可写,
cosnt参数接收const对象,属于权限的平移,被允许。接收普通对象,属于权限的缩小,被允许。
普通参数接收普通对象,属于权限的平移,被允许。接收const对象,属于权限的放大(将只读权限更改为可读可写),不被允许。
3.成员函数之析构函数
函数解释:程序结束是销毁string对象指向的空间,无需手动调用
4.成员函数之赋值运算符重载
赋值运算符是两个已经存在的string对象进行赋值操作
string(1) string& operator=(const string& str);
函数解释:赋值,用新的字符串取代旧的字符串
string(2) string& operator=(const char* s);
函数解释:赋值,用指针指向的新的字符串取代旧的字符串
string(3) string& operator=(char c);
函数解释:赋值,用新的字符取代旧的字符串
5.非成员函数的重载
5.1operator+
函数解释:并不会改变原本字符串,可以直接输入lhs(左字符串)+rhs(右字符串)的结果。如下图
5.2operator>>
函数解释:输入运算符重载。完成写操作(在黑框框中写入)
5.3operator<<
函数解释:输出运算符重载。完成读操作(在黑框框中显示)
6.访问字符串数据的接口函数
6.1对[]的运算符重载
对[]进行运算符重载后,使得字符串类也支持下标随机访问
函数解释:返回字符串pos下标位置的字符。如下图
返回字符串pos下标位置的字符,pos的大小要小于字符串的长度(否则会抛异常)
7.修改字符串的常用函数
7.1operator+=
函数解释:在当前字符串的结尾追加字符串
用法:如下图
7.2append
函数解释:为字符串追加字符串。相比+=有了更多的玩法。
string(1):直接追加字符串。
string(2):从字符串str下标为subpos的位置追加sublen个字符串,如果没有传参数给sublen或者str太短,则追加str的全部字符。如下图
7.3insert
函数解释:在字符串的下标为pos的位置前插入额外的字符。插入位置后原本位置的数据会在插入的数据后。
用法:
string(1):如下图
single character(6)
7.4 erase
函数解释:
string(1):从字符串下标为pos的位置删除长度为len个字符,pos默认为下标0,len默认到字符串结尾。
string(2):删除迭代器指向位置的字符。
string(3):删除从first位置到last位置的字符。(只删first下标的字符,不删除last下标的字符)。如下图
7.5push_back
函数解释:尾插,字符串尾部插入一个字符。如下图