1. mutable ,可变数据成员声明
在一个类中的变量之前加入mutable声明,可以使得整个成员在const类型的函数中都可以改变
举例如下:
class TYPE
{
friend class TYPE2;
int x1, x2;
public:
TYPE(int m1, int m2) :x1(m1), x2(m2){};
void run()
{
cout << x1 << " " << x2;
}
private:
int q1, q2;
int add(int s1, int s2)
{
return s1 + s2;
}
};
class TYPE2
{
public:
TYPE2()
{
x1 = 10;
x2 = 20;
}
int multi (TYPE s1, int n1, int n2)const
{
n1 = s1.add(n1, n2);
x2 = n1;
return n1*x2;
}
private:
mutable int x1, x2;
};
int divs(int x1, int x2)
{
return x1 / x2;
}
int main()
{
TYPE s1(10, 10);
TYPE2 s2;
int result = s2.multi(s1, 10, 20);
cout << result << endl;
return 0;
}
上例子中可以看到,原本x2
的值是不可以改变的,因为函数是const
类型的,const
加在后面代表的是这个函数中的类的成员变量不可以修改,但加上mutable
关键字后,这个成员变量就可以修改了。
2. 类类型
- 在类中,即使两个类列表完全一致,但名字不同也不是一个类,不能相互赋值。
- 聚合类,即为结构体
- 在类中想要定义静态成员函数时,并且想在类中声明,在外部定义,则在类中声明时必须使用static 关键字,但在外部定义的时候一定不能再使用static关键字了。
3. IO库
- 流对象不能拷贝和赋值
使用流读取文件:
#include "stdafx.h"
#include<iostream>
#include<string>
#include<vector>
#include<sstream>
#include<fstream>
using namespace std;
int main()
{
/*=============================输入文件=========================================*/
string fileName = "123.txt"; // 文件名
ifstream fstr(fileName.c_str()); // 文件读取流创建
string lineStr; // 保存读取流进入后的行内容
stringstream inputStream; // 将行内容转到string流中
string printStr; // 每行内容字符打印
vector<string> result;
while (getline(fstr, lineStr)) // 读取文件流中内容行,给到lineStr
{
inputStream << lineStr; // 行内容放置到string流中
while (inputStream >> printStr)
{
result.push_back(printStr);
}
inputStream.clear(); // string流清除,否则永远是第一行内容
}
fstr.close(); // 文件流关闭
/*=============================输出文件=========================================*/
ofstream outfile;
outfile.open("234.txt");
for (int i = result.size() - 1; i >= 0; i--)
{
outfile << result[i] << " ";
}
outfile << endl;
for (int i = 0; i < result.size(); i++)
{
outfile << result[i] << " ";
}
outfile << endl;
return 0;
}
4. 容器
4.1 容器总共有以下几种:
- vector
- deque
- list
- forward_list
- array
- string
4.2 容器操作
c.insert(c.begin(),2)
, insert插入操作,第一个参数是插入的位置,是指向这个元素之前的位置进行插入,后面是插入的内容
举例子“”
vector<int> arr1{ 1,2,3,4,8,9 };
vector<int> arr2{ 4,5,6 };
arr1.insert(arr1.begin()+3,arr2[1]);
此例中,插入的位置在arr1向量的元素3之后,4之前,指向的位置是4之前。
还可以插入一段数组,比如:
vector<int> arr1{ 1,2,3,4,8,9 };
vector<int> arr2{ 4,5,6 };
arr1.insert(arr1.begin(), arr2.begin(),arr2.end());
即可以指定一个范围内的数据插入。 调用insert,可以返回插入元素之前的位置的迭代器。
c.erase(c.begin())
: 删除的是c的首位元素,即这个删除操作就是想删除哪里就指向哪里c.emplace(c.begin(),2)
:和insert作用一样,都是插入元素,但它最大的作用是避免产生不必要的临时变量c.emplace_back(2)
:和push_back功能一样,但最大的好处是不需要触发拷贝构造和转移构造。而且调用形式更加简洁swap(a,b)
,orswap(a[0],b[0])
:交换a和b的元素,或者交换a[0]和b[0]的元素。c.rbegin()
:返回指向c的尾元素的迭代器c.rend()
:返回指向c的首元素之前的位置的迭代器c.assign(b,e)
:c替换为迭代器b和e范围内的元素 assign只能顺序容器使用c.assign({1,3,4,})
:c替换为初始化列表的元素c.assign(n,t)
:c替换为n个值为t的元素array<int,3>
:数组,定义时需要制定array类型和大小,内置类型的数组不支持拷贝赋值,但array可以c.front()
:返回容器c的首元素的引用,c.back()
:返回容器c的尾元素的引用c.at(n)
:返回下标为n的引用。c.pop_back()
:删除首元素c.pop_front()
:删除尾元素c.erase(b,e)
:删除c的b到e迭代器之间的元素
5. string操作
s.substr(0,4)
:返回子串,位置+个数,位置不可以用迭代器s.substr(n)
:返回子串,从第n个位置开始到最后s.insert(n,m)
: 在位置n之前插入m,但这个位置不可以使用迭代器s.insert(0,s2,0,m)
:在0之前插入s2中从0开始的m个字符。s.erase(n,m)
:从位置n出删除m个字符s.append(s1,0,m)
:在s的末尾插入s1从0开始的m个字符s.replace(n,m,s1,0,p)
:在s的n位置除删除m个字符,替换为s1的从0开始的p个字符s.replace(s.begin()+1,s.beign()+3, s1)
:将s的第二个元素到第四个元素之前的元素删除,不包括第四个元素,然后替换为s1s.assign(s1,0,m)
:将s替换为s1的从0开始的m个字符s.find(s1)
:在s中查找s第一次出现的位置,找到则返回位置下标,找不到则返回-1s.find_first_of(s1)
:在s中查找第一个存在于s1中的字符,返回s中的下标s.find_first_not_of(s1)
:在s中查找第一个不在s1中的字符,返回s中的下标s.rfind(s1)
:返回s中最后一个s1出现的位置to_string(222)
:将222转换为字符串stoi(s)
:将字符串转换为int类型
字符串的操作即为:位置+个数
6. 顺序容器适配器
stack
queue
priority_queue
stack 和queue是基于deque实现的,priority_queue是基于vector实现的
栈适配器:
s.pop()
s.push()
s.top()
队列适配器queue:
q.pop()
q.front()
q.back()
q.push()
7. 泛型算法
算法头文件为:algorithm,numeric,
auto flag = find(res.begin(),res.end(),m)
:在res的范围内寻找m,找到了则指向这个元素,找不到则返回res.end()int nums = accumulate(vec.begin(),vec.end(),0)
:计算向量vec的和,后面值为初始值,头文件为numericbool flag = equal(res1.begin(),res1.end(),res2.begin())
:比较res1 和res2的元素,res2长度>=res1,如果res1的元素都能再res2找到,则返回1,否则返回0fill(res1.begin(),res1.end(),3)
:将res1的迭代器范围内的元素都替换为3fill_n(vec.begin(),vec.size(),7)
:向空向量中增加元素,迭代器首+向量尺寸+元素内容back_inserter(vec); fill_n(back_inserter(vec),10,0)
:back_inserter(vec)返回的是一个插入迭代器,然后就可以往空向量中插入元素copy(send.begin(),send.end(),receive.begin())
:copy接收三个参数,前两个表示要拷贝的串的范围,可以是迭代器,也可以是指针,后面的参数表示的是目标的起始位置迭代器,或者指针。即我们可以用来实现数组的拷贝。
数组拷贝的例子:
int arr1[] = { 1,2,3,4 };
int arr2[sizeof(arr1) / sizeof(*arr1)];
int *start = &arr2[0];
copy(begin(arr1), end(arr1), start);
replace(begin(arr1), end(arr1),2,50 );
:将搜寻范围内等于2的,将其替换为50replace_copy(begin(arr1), end(arr1),back_inserter(ivec),2,50 );
:将搜寻范围内等于2的,将其替换为50`,此算法接收三个迭代器,前两个表示范围,第三个表示存入的向量的起始位置。这个可以保证我搜寻的范围的向量不变,可以将调整后的向量保存在ivec中sort(vec.begin(),vec.end())
:排序- auot flag = unique(vec.begin(),vec.end())`:返回不重复区域之后的那个位置迭代器
vec.erase(flag,vec.end())
:清除