C++知识点3

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),or swap(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的第二个元素到第四个元素之前的元素删除,不包括第四个元素,然后替换为s1
  • s.assign(s1,0,m):将s替换为s1的从0开始的m个字符
  • s.find(s1):在s中查找s第一次出现的位置,找到则返回位置下标,找不到则返回-1
  • s.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的和,后面值为初始值,头文件为numeric
  • bool flag = equal(res1.begin(),res1.end(),res2.begin()):比较res1 和res2的元素,res2长度>=res1,如果res1的元素都能再res2找到,则返回1,否则返回0
  • fill(res1.begin(),res1.end(),3):将res1的迭代器范围内的元素都替换为3
  • fill_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的,将其替换为50
  • replace_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()):清除
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值