c++ STL 标准库

目录

1、类型转换

static_cast  (1、用于内置的数据类型 2、具体继承关系(父子继承)的指针和引用)

dynamic_cast 转换具有继承关系的指针或者引用,在转换前会进行对象类的检查、

const_cast 用于const 和非const属性的转换

2、异常机制

 3、标准输入流

5、文本文件操作

6、二进制文件读写

7、STL

7.1 小案例

7.2、string

8、vector

9、队列

案例

10、 set/multiset

set更改排序,规则

 pair对组

11、map 

案例

容器深拷贝和浅拷贝问题

ptr_fun 函数对象适配器(将普通函数转换成函数对象)


1、类型转换

static_cast  (1、用于内置的数据类型 2、具体继承关系(父子继承)的指针和引用)

#include<iostream>

using namespace std;

class Building{};
class Animal{};
class Cat:public Animal{};


//static_cast
void tes1()
{
	int a = 97;
	char  c = static_cast<char>(a);
	cout << c << endl;

}

基础数据类型指针
//int* p = 0;
//char* sp = static_cast<char*>(p);    //类型转换无效
//
对象指针
//Building* building = 0;
//Animal* ani = static_cast<Animal*>(building); //类型转换无效

//转换具有继承关系的对象指针(父子继承)
Animal* ani1 = 0;
Cat* cat = static_cast<Cat*>(ani1);  //可以进行类型转化

//转换具有继承关系的引用
Animal Father;
Animal& Dad = Father;
Cat& son = static_cast<Cat&>(Dad);  //可以转换

 //static_cast  用于内置的数据类型,
	//			还具有继承关系的指针或者引用;

int main()
{
	tes1();
	
	
}

dynamic_cast 转换具有继承关系指针或者引用,在转换前会进行对象类的检查、

 

const_cast 用于const 和非const属性的转换

const int *p=0;
int *p2 = const_cast<int *>(p);


int *p=0;
const int *p3 = const_cast<const int *>(p)

2、异常机制

#include<iostream>

using namespace std;



//异常的基本语法
int divide(int x, int y)
{
	if (y == 0)
		throw y;			//抛异常
	return x / y;
}

void test()
{
							//尝试着去捕获异常
	try {
		divide(10, 0);
	}
	catch (int i){			//异常时根据抛出异常的数据类型进行类型匹配 , i = y;  也可以"..."代表自适应数据类型
		cout << "除数不能为:"<<i <<"!"<< endl;

	}
}




int main()
{
	
	test();

}

 3、标准输入流

#include<iostream>
#include<string>
using namespace std;

//标准输入流 cin.get()
void test()
{
	char ch;
	while ((ch = cin.get()) != EOF) {   //从缓冲区中取一个字符
		cout << ch << endl;
	}

	
	char buf[256] = {0};

	 cin.get(buf, 256);			//取一个字符串

	 cin.getline(buf, 256);		//读取一行

}

void test1()
{
	char ch;
	cin.get(ch);    
	cout << ch<<endl;
	cin.ignore(n);//从缓冲区中忽视n个字符
	cin.get(ch);
	cout << ch << endl;

}

void test2()
{
    cout<< "请输入数组或者字符串:" <<endl;
    char ch;
    ch = cin.peek();       //读一下缓冲区,返回第一个字符;(并不取走)
    if(ch >= '0' && ch <= '9')
    {
        int number;
        cin >> number;
        cout << "您输入的是数字:" << number <<endl;
    }
    else {
        char buf[256] = {0};
        cin >> buf;
        cout << "您输入的是字符串:"<< buf << endl;
    }

}



int main()
{
	test1();
} 

#include<iostream>
#include<string>

#include<iomanip>

using namespace std;

//标准输出流
void test1()
{
	cout << "HELLO" << endl;
	//cout.flush();				//刷新缓冲区
	cout.put('p').put('u').put('a') << endl;	//连续输出字符
	cout.write("hello world!", strlen("hello world!")); //输出字符串
}

//格式化输出

void test2()
{
	//成员方法的方式
	int n = 10;
	cout << n<< endl;
	
	cout.unsetf(ios::dec);	//卸载当前默认的10进制的输出方式
	cout.setf(ios::oct);	//设置以八进制的输出方式
	cout.setf(ios::showbase); //打印进制标识符
	
	cout << n << endl;
	cout.unsetf(ios::oct);
	cout.setf(ios::hex);	//设置十六进制
	cout << n << endl;

	cout.width(10);			//宽度为 10
	cout.fill('*');			//填充 '*'
	cout.setf(ios::left);	//左靠齐输出
	cout << n << endl;


}

void test3()
{

	/**********通过控制符方式(需要引用头文件"#include<iomanip>")***********/
	int n2 = 100;
	cout << hex
		<< setiosflags(ios::showbase)
		<< setw(10)
		<< setfill('^')
		<< setiosflags(ios::left)
		<<n2
		<< endl;
}
int main()
{
	test3();
}

5、文本文件操作

#include<iostream>
#include<fstream>

using namespace std;

//文本文件的读写

void test()
{
	char* txt = (char*)"C:\\Users\\prince\\Desktop\\demo.txt";	  //存放读取文件所在路径
	char* txt1 = (char*)"C:\\Users\\prince\\Desktop\\demo1.txt";  //存放文件所在路径

	//ifstream iopen(txt,ios::in);			//以只读方式打开文件
	ifstream iopen;				//创建 "读文件" 对象
	ofstream iwrite;			//创建  "写文件" 对象


	iopen.open(txt, ios::in);				//以只读的方式打开文件
	iwrite.open(txt1, ios::out|ios::app);			//以写的方式打开文件  "iOS::app"在文件后面进行追加

	if (!iopen)
	{
		cout << "打开文件失败!" << endl;
		return;
	}

	//读取文件
	char ch;
	while (iopen.get(ch))
	{
		cout << ch;
		iwrite.put(ch);
	}

	//关闭文件
	iopen.close();
	iwrite.close();

}

int main()
{
	test();

}

6、二进制文件读写

#include<iostream>
#include<fstream>

using namespace std;

//文本文件的读写

void test()
{
	char* txt = (char*)"C:\\Users\\prince\\Desktop\\demo.txt";	  //存放读取文件所在路径
	char* txt1 = (char*)"C:\\Users\\prince\\Desktop\\demo1.txt";  //存放文件所在路径

	//ifstream iopen(txt,ios::in);			//以只读方式打开文件
	ifstream iopen;				//创建 "读文件" 对象
	ofstream iwrite;			//创建  "写文件" 对象


	iopen.open(txt, ios::in);				//以只读的方式打开文件
	iwrite.open(txt1, ios::out|ios::app);			//以写的方式打开文件  "iOS::app"在文件后面进行追加

	if (!iopen)
	{
		cout << "打开文件失败!" << endl;
		return;
	}

	//读取文件
	char ch;
	while (iopen.get(ch))
	{
		cout << ch;
		iwrite.put(ch);
	}
	
	//关闭文件
	iopen.close();
	iwrite.close();

}

//二进制文件操作 对象序列化
class person {
public:
	person(int age1,int id1):age(age1),id(id1){}

	void show() {
		cout << "Age:" << age << "Id:" << id << endl;
	}
private:
	int age;
	int id;
};

void test1()
{

	person p1(10, 20), p2(30, 40);  //以二进制形式进行存储
	//把p1  p2写进文件里

	char* filename = (char*)"C:\\Users\\prince\\Desktop\\demo1.txt";

	ofstream osm;
	ifstream ism;

	osm.open(filename, ios::out | ios::binary);   //"" ios::binary" 以二进制方式进行读写操作"
	osm.write((char*)&p1, sizeof(p1));  //二进制的方式进行写文件
	osm.write((char*)&p2, sizeof(p2));

	ism.open(filename, ios::in | ios::binary);
	ism.read((char*)&p2, sizeof(person));

	osm.close();
	ism.close();
}

int main()
{
	test1();

}

7、STL

7.1 小案例

#include<iostream>

#include<vector>
#include<algorithm>  //STL算法头文件

using namespace std;

void show(int v)  //回调函数
{
	cout << v << endl;
}

//STL基本语法
void test()
{
	vector<int> v;
	v.push_back(10);
	v.push_back(20);
	v.push_back(30);
	v.push_back(40);
	v.push_back(50);
	v.push_back(60);

	//通过STL提供的算法"for_each"进行遍历
	//容器提供的迭代器
	//vector<int>::iterator 拿到当前容器的迭代器类型

	vector<int>::iterator ibegin = v.begin();  //" ibegin"当作是一个指针
	vector<int>::iterator iend = v.end();

	for_each(ibegin, iend,show);  //"for_each从容器中遍历的每一个数值都将通过回调函数 "show()"进行操作"

	
}

//容器也可以存放自定义数据类型
class Person {

public:
	Person(int age1,int id1):age(age1),id(id1){}
	void printPerson()
	{
		cout << "age:" << age << endl;
		cout << "id:" << id << endl;
		cout << endl;
	}

private:
	int age;
	int id;
};

void test1() {
	vector<Person> v;
	Person p1(10, 20), p2(20, 10), p3(11, 22), p4(13, 30);
	
	v.push_back(p1);
	v.push_back(p2);
	v.push_back(p3);
	v.push_back(p4);

	//遍历
	for (vector<Person>::iterator iter = v.begin(); iter != v.end(); iter++)
	{
		(*iter).printPerson();

	}
}



int main()
{
	test1();
}

7.2、string

#include<iostream>

#include<string>

using namespace std;

//初始化
void test()
{
	string s1;	//调用无参构造
	string s2(10, 'a');
	string s3("abcdefg");
	string s4(s3);	//拷贝构造

}

//赋值操作
void test1()
{
	string s1;
	string s2("appp");
	s1 = "abcdefg";
	cout << s1 << endl;
	s1 = s2;
	cout << s1 << endl;
	s1 = 'a';
	cout << s1 << endl;

	//成员函数"assign()进行赋值操作"
	s1.assign("jk1");
	cout << s1 << endl;

}

//取值操作
void test2()
{
	string s1 = "abcdefg";

	//重载[]操作符
	for (int i = 0; i < s1.size(); i++) {
		cout << s1[i] << " ";
	}
	cout << endl;

	// at 成员函数
	for (int i = 0; i < s1.size(); i++)
	{
		cout << s1.at(i) << " ";
	}
	
	//区别: []方式 如果访问越界,直接挂了
	//		at 方式 访问越界 抛异常 out_of_range 
	try {
		cout << s1.at(100) << endl;
	}
	catch (...) {  //"自动匹配所抛出异常的类型"

	}

}

//拼接操作
void test3()
{
	string s = "abc";
	s += "erf";
	string s1 = "123";
	s += s1;



	string s2 = "24e3";
	s2.append(s1);
	cout << s2 << endl;

	string s3 = s1 + s2;
	cout << s3 << endl;
}

//查找操作
void test4() {
	string s = "12345defgjk7fg2";
	//查找第一次出现的位置
	int pos = s.find("fg");
	cout << "pos:" << pos<<endl;

	//查找最后一次出现的位置
	int pos1 = s.rfind("fg");
	cout << "pos1:" << pos1 << endl;
}

//string 替换
void test5() {
	string s = "abcdefg";
	s.replace(0,2,"111");	 //将0~2位置上的字符替换成"111";
	cout << s << endl;
}

//string比较
void test6()
{
	string s1 = "abcd";
	string s2 = "abce";
	if (int n = s1.compare(s2) == 0)   //"compare()"区分大小写 ; 排在前面的字母越小 ;大写字母比小写字母小。
		cout << "字符串相等" << endl;
	else if (n > 1)
		cout << "S1 > S2" << endl;
	else
		cout << "s2 > s1" << endl;
}

//子串操作
void test7()
{
	string s = "abcdefg";
	string sub_str = s.substr(2, 5);	//选取子串内容
	cout << sub_str << endl;
}

//插入和删除
void test8()
{
	string s = " abcdefg";
	cout << s << endl;

	s.insert(3, "123");  //在第三个前面的位置插入
	cout << s << endl;
	
	s.erase(2, 4);
	cout << s << endl;

}

int main()
{
	test8();
}

8、vector

#include<iostream>

#include<vector>

using namespace std;

void show(vector<int>& v)
{

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

//初始化
void test()
{
	vector<int> v1; //默认构造

	int arr[] = { 10,20,30,40,50 };
	vector<int> v2(arr, arr + size(arr) );
	vector<int> v3(v2.begin(), v2.end());
	vector<int> v4(v3);

}

//常用的赋值操作
void test1()
{
	int arr[] = { 10,20,30,40,50 };
	vector<int> v2(arr, arr + size(arr));

	//成员函数方法
	vector<int> v3;
	v3.assign(v2.begin(), v2.end()); //也可以使用迭代器赋值

	//重载 =
	vector<int> v4;
	v4 = v3;
	show(v4);

	//交换
	int arr1[] = {100,200,201,301,400};
	vector<int>v5(arr1,arr1+size(arr1));
	show(v5);
	v5.swap(v4); 
	show(v5);

	v4.empty();	//检查是否为空

	//空间大小操作
	cout << "**************" << endl;
	show(v4);
	v4.resize(3);
	show(v4);	  //(缩小)调整大小
	v4.resize(8); // (扩大)
	show(v4);
	
	//重载算符(不抛异常)
	for (int i = 0; i < v4.size(); i++)
		cout << v4[i] << " ";
	cout << endl;

	//使用成员函数好点(会抛出异常)
	for (int i = 0; i < v4.size(); i++)
		cout << v4.at(i) << " ";
	cout << endl;

}

//插入和删除
void test2()
{
	vector<int> v;
	v.push_back(10);
	v.push_back(20);
	v.insert(v.begin(), 30); //头插
	v.insert(v.end(), 69);	//尾插
	v.insert(v.begin()+2, 69); // vector 支持随机访问
	show(v);

	cout << "**************" << endl;
	v.erase(v.begin());
	show(v);
	v.erase(v.begin() + 2, v.end());
	show(v);
}

//巧用swap()缩减空间
void test3()
{
	//vector 添加元素 他会自动增长 你删除元素时候,会自动减少嘛?

	vector<int> v;
	for (int i = 0; i < 100000; i++) {
		v.push_back(i);
	}

	cout << "size:" << v.size() << endl;
	cout << "capacity:" << v.capacity() << endl;

	cout << "---------------------" << endl;

	v.resize(100);
	cout << "size:" << v.size() << endl;   //改变当前村的数据的数量
	cout << "capacity:" << v.capacity() << endl;

	cout << "---------------------" << endl;

	//收缩空间
	vector<int>(v).swap(v);   //收缩空间
	cout << "size:" << v.size() << endl;   
	cout << "capacity:" << v.capacity() << endl;
}

void test4() {

	//reserve预留空间  resize 区别
	
	int num = 0;
	int* address=0;

	vector<int> v;
	v.reserve(100000);   //预先开辟空间
	for (int i = 0; i < 100000; i++)
	{
		v.push_back(i);
		if (address != &(v[0])) {  // "&v"是这个容器内的首地址,"&(v[0])"才是这个容器内值的首地址
			address = &(v[0]);
			num++;
		}
	}
	cout << "num:" << num << endl;
}

int main()
{
	test4();
}#include<iostream>

#include<vector>

using namespace std;

void show(vector<int>& v)
{

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

//初始化
void test()
{
	vector<int> v1; //默认构造

	int arr[] = { 10,20,30,40,50 };
	vector<int> v2(arr, arr + size(arr) );
	vector<int> v3(v2.begin(), v2.end());
	vector<int> v4(v3);

}

//常用的赋值操作
void test1()
{
	int arr[] = { 10,20,30,40,50 };
	vector<int> v2(arr, arr + size(arr));

	//成员函数方法
	vector<int> v3;
	v3.assign(v2.begin(), v2.end()); //也可以使用迭代器赋值

	//重载 =
	vector<int> v4;
	v4 = v3;
	show(v4);

	//交换
	int arr1[] = {100,200,201,301,400};
	vector<int>v5(arr1,arr1+size(arr1));
	show(v5);
	v5.swap(v4); 
	show(v5);

	v4.empty();	//检查是否为空

	//空间大小操作
	cout << "**************" << endl;
	show(v4);
	v4.resize(3);
	show(v4);	  //(缩小)调整大小
	v4.resize(8); // (扩大)
	show(v4);
	
	//重载算符(不抛异常)
	for (int i = 0; i < v4.size(); i++)
		cout << v4[i] << " ";
	cout << endl;

	//使用成员函数好点(会抛出异常)
	for (int i = 0; i < v4.size(); i++)
		cout << v4.at(i) << " ";
	cout << endl;

}

//插入和删除
void test2()
{
	vector<int> v;
	v.push_back(10);
	v.push_back(20);
	v.insert(v.begin(), 30); //头插
	v.insert(v.end(), 69);	//尾插
	v.insert(v.begin()+2, 69); // vector 支持随机访问
	show(v);

	cout << "**************" << endl;
	v.erase(v.begin());
	show(v);
	v.erase(v.begin() + 2, v.end());
	show(v);
}

//巧用swap()缩减空间
void test3()
{
	//vector 添加元素 他会自动增长 你删除元素时候,会自动减少嘛?

	vector<int> v;
	for (int i = 0; i < 100000; i++) {
		v.push_back(i);
	}

	cout << "size:" << v.size() << endl;
	cout << "capacity:" << v.capacity() << endl;

	cout << "---------------------" << endl;

	v.resize(100);
	cout << "size:" << v.size() << endl;   //改变当前村的数据的数量
	cout << "capacity:" << v.capacity() << endl;

	cout << "---------------------" << endl;

	//收缩空间
	vector<int>(v).swap(v);   //收缩空间
	cout << "size:" << v.size() << endl;   
	cout << "capacity:" << v.capacity() << endl;
}

void test4() {

	//reserve预留空间  resize 区别
	
	int num = 0;
	int* address=0;

	vector<int> v;
	v.reserve(100000);   //预先开辟空间
	for (int i = 0; i < 100000; i++)
	{
		v.push_back(i);
		if (address != &(v[0])) {  // "&v"是这个容器内的首地址,"&(v[0])"才是这个容器内值的首地址
			address = &(v[0]);
			num++;
		}
	}
	cout << "num:" << num << endl;
}

int main()
{
	test4();
}

9、队列

案例

//评委打分案例( sort 算法排序)
//创建5个选手(姓名,得分),10个评委对5个选手进行打分
//得分规则:去除最高分,去除最低分,取出平均分
//按得分对5名选手进行排名


#include<iostream>
#include<deque>
#include<algorithm>
#include<vector>
#include<string>

using namespace std;

//选手类
class Player {
public:
	Player(){}
	Player(string name1,int score1):name(name1),score(score1){}

public:
	string name;
	int score;
};

//创建选手
void Creat_player(vector<Player>& v)
{
	string nameSeed = "ABCDE";
	for (int i = 0; i < size(nameSeed); i++)
	{
		Player p;
		p.name = "选手";
		p.name +=nameSeed[i];
		p.score = 0;
		v.push_back(p);
	}
}

//打分
void Set_Score(vector<Player>& v)
{
	for (vector<Player>::iterator iter = v.begin(); iter != v.end(); iter++) {
		
		//当前学生进行打分
		deque<int> dScore;
		for (int i = 0; i < 10; i++)
		{
			int score = rand() % 41 + 60;  //" rand ()%41" 产生一个 0~40 之间的随机数
			dScore.push_back(score);
		}
		//对分数进行排序 //"sort()默认从小到大"
		sort(dScore.begin(), dScore.end());

		//去除最高和最低分
		dScore.pop_front();
		dScore.pop_back();

		//求平均分
		int total = 0;
		for (deque<int>::iterator it = dScore.begin(); it != dScore.end();it++) {
			total += (*it);
		}
		int average = total / dScore.size();
		(*iter).score = average;
	}
}

//排序规则
bool mycompare(Player& p1, Player& p2)
{
	//return p1.score < p2.score; //从小到大排序
	return p1.score > p2.score; //从大到小排序
}

//排名 sort默认从小到大(第三个参数为缺省 (可以不写)),我们希望从大到小
void Print_Rank(vector<Player>& v)
{
	//排序
	sort(v.begin(), v.end(), mycompare);
	for (vector<Player>::iterator iter = v.begin(); iter != v.end(); iter++)
	{
		cout << "姓名:" << (*iter).name << " " << "得分:" << (*iter).score << endl;
	}
}


int main()
{
	//定义vector容器,保存选手信息
	vector<Player>vplist;
	Creat_player(vplist);
	Set_Score(vplist);
	Print_Rank(vplist);

}

10、 set/multiset

#include<iostream>
#include<set>

using namespace std;



//set容器初始化
void test()
{
	set<int> s1;	   //自动排序默认从小到大
	
	s1.insert(1);
	s1.insert(21);
	s1.insert(31);
	s1.insert(14);
	s1.insert(15);

	for (set<int>::iterator it = s1.begin(); it != s1.end(); it++)
	{
		cout << (*it) << " ";
	}
	cout << endl;

	//赋值操作
	set<int>s2;
	s2 = s1;
	
	//删除操作
	s1.erase(s1.begin());
	for (set<int>::iterator it = s1.begin(); it != s1.end(); it++)
	{
		cout << (*it) << " ";
	}
	cout << endl;


	//查找操作
	set<int>::iterator ret = s1.find(31);
	if (ret == s1.end())
		cout << "没有找到";
	else
	{
		cout <<"ret"<< (*ret) << endl;
	}

	//找第一个大于等于key的目标元素
	ret = s1.lower_bound(2);
	if (ret == s1.end())
		cout << "没有找到";
	else
	{
		cout << "ret" << (*ret) << endl;
	}

	//如何改变默认排序?
}

int main()
{
	test();
}

set更改排序,规则

#include<iostream>
#include<set>

using namespace std;
//仿函数
class Mycompare
{
public:
	 bool operator()(const int& v1, const int &v2) const
	 {
		return v1 > v2;
	}

};



//set容器从大到小排序
void test()
{
	//如何改变默认排序?(改成从大到小)  (需要自行做一个比较类)设置仿函数
	set<int,Mycompare>s3;
	s3.insert(26);
	s3.insert(21);
	s3.insert(12);
	s3.insert(22);
	s3.insert(24);
	for (set<int>::iterator iter = s3.begin(); iter != s3.end(); iter++)
	{
		cout << (*iter) << " ";
	}
	cout << endl;

}

/********************************************************/
class person
{
public:
	person(string name, int age)
	{
		this->m_name = name;
		this->m_age = age;
	}
	string m_name;
	int m_age;
};

class mycompare2
{
public:
	bool operator()(const person& p1, const person& p2)const  //需要添加const 

		// 这个位置要加const修饰
	{
		if (p1.m_age > p2.m_age) //降序
		{
			return true;
		}
		return false;
	}
};

void test3()
{
	set<person, mycompare2> p;
	person p1("sss", 35);
	person p2("aaa", 10);
	person p3("bbb", 20);
	person p4("ccc", 46);
	person p5("ddd", 82);
	p.insert(p1);
	p.insert(p2);
	p.insert(p3);
	p.insert(p4);
	p.insert(p5);
	//插入自定义数据类型 需要指定排序规则
	//显示
	for (set<person, mycompare2>::iterator it = p.begin(); it != p.end(); it++)
	{
		cout << "姓名: " << (*it).m_name << "年龄: " << it->m_age << endl;
	}
}



int main()
{
	test3();
}

 pair对组

11、map 

 

#include<iostream>
#include<map>

using namespace std;


//map容器初始化
void test()
{
	//map容器模板参数,第一个参数key的类型,第二参数value类型
	map<int, int>mymap;


	//插入数据 pair.first key 值 pair.second  value值
	//第一种方法
	mymap.insert(pair<int, int>(10, 10));
	//第二种
	mymap.insert(make_pair(20, 20));
	//第三种
	mymap.insert(map<int, int>::value_type(30, 30));


	//第四种
	mymap[40] = 40;
	//对于第四种插入值的方法
	//发现如果key不存在,则会创建pair插入到map容器中 
	//如果发现key存在 ,则会修改相对应 key 的 value 

	//打印
	for (map<int, int>::iterator it = mymap.begin(); it != mymap.end(); it++)
	{
		// *it 取出的是一个pair
		cout << "key:" << (*it).first << "  value:" << (*it).second << endl;
	}

	//询问不存在的 "key" ,则会创建 key-value 

	cout << "mymap[60]:" << mymap[60] << endl;


	//打印
	for (map<int, int>::iterator it = mymap.begin(); it != mymap.end(); it++)
	{
		// *it 取出的是一个pair
		cout << "key:" << (*it).first << "  value:" << (*it).second << endl;
	}

}

//创建类的map

class MyKey {
public:
	MyKey(int index, int id):mIndex(index),mID(id){}
	
public:
	int mIndex;
	int mID;
};

//仿函数
class MyCompare {
public:
	bool operator()(const MyKey &v1, const MyKey &v2) const   //需要添加  const 
	{
		return v1.mIndex > v2.mIndex;
	}
};

void test2()
{
	map<MyKey, int,MyCompare> mymap;   //自定义排序规则  class mycompare 

	mymap.insert(make_pair(MyKey(1,2), 10));
}


int main()
{

	test2();
}

案例

#include<iostream>
#include<map>
#include<vector>
#include<string>

using namespace std;

//multimap案例
//公司今天招聘了5个员工,5名员工进入公司之后,需要指派员工在那个部门工作
//人员信息有:姓名 年龄 电话 工资 等组成
//通过Multimap进行信息的插入保存显示 
//分部门显示员工信息显示全部员工信息

#define XiaoShou 1	//销售部门
#define YanFa 2		//研发部门
#define CaiWu 3		//财务部门


class Worker {
public:
	Worker(){}
	string mName;
	string mTele;
	int mAge;
	int mSalary;
	
};

//创建员工
void Create_Worker(vector<Worker> &vWorker)
{
	string sName  = "ABCDE";
	for (int i = 0; i < 5; i++)
	{
		Worker worker;
		worker.mName = "员工";
		worker.mName += sName[i];

		worker.mAge = rand() % 10 + 20;

		worker.mTele = "010-222222222";

		worker.mSalary = rand() % 10000 + 10000;

		//保存员工信息
		vWorker.push_back(worker);
	}
	/*for (vector<Worker>::iterator it = vWorker.begin(); it != vWorker.end(); it++)
	{
		cout << (*it).mName << " " ;
	}
	cout << endl;*/


}

//员工分组
void WorkerByGroup(vector<Worker> & vWorker, multimap<int, Worker>&WorkerGruop)
{
	//将员工随机分配到不同部门
	for (vector<Worker>::iterator it = vWorker.begin(); it != vWorker.end(); it++)
	{
		int dpartId = rand() % 3 + 1;
		switch (dpartId)
		{
		case XiaoShou:
			WorkerGruop.insert(make_pair(XiaoShou,(*it)));
			break;
		case YanFa:
			WorkerGruop.insert(make_pair(YanFa, (*it)));
			break;
		case CaiWu:
			WorkerGruop.insert(make_pair(CaiWu, (*it)));
			break;

		default:
			break;
		}

	}


	/*for (multimap<int,Worker>::iterator it=WorkerGruop.begin(); it != WorkerGruop.end(); it++)
	{
		cout <<"部门:"<<(*it).first  <<"部门人数为:"<<WorkerGruop.count((*it).first)<< " 姓名:" << (*it).second.mName << "  年龄:" << (*it).second.mAge << " 电话:" << (*it).second.mTele << " 工资:" << (*it).second.mSalary << endl;
	}*/

}

void showGroupWorkers(multimap<int, Worker>&WorkerGruop, int departId)
{
	multimap<int, Worker>::iterator it = WorkerGruop.find(departId);

	//找到当前部门的总人数
	int count = WorkerGruop.count(departId);
	cout << "当前部门为" << departId << "  人数为:" << count << endl;
	int num = 0;
	for (it; it != WorkerGruop.end() && num < count; it++, num++)
	{
		cout << " 姓名" << (*it).second.mName << "  年龄:" << (*it).second.mAge << " 电话:" << (*it).second.mTele << " 工资:" << (*it).second.mSalary << endl;
	}
	cout << endl;
}

void PrintWorkerByGroup(multimap<int ,Worker>WorkerGruop)
{
	//打印销售部员工信息
	showGroupWorkers(WorkerGruop, XiaoShou);

	showGroupWorkers(WorkerGruop, YanFa);

	showGroupWorkers(WorkerGruop, CaiWu);


}


int main()
{
	//存放员工的信息
	vector<Worker> vWorker;
	//multimap保存分组信息
	multimap<int, Worker> WorkerGruop; 

	//创建员工
	Create_Worker(vWorker);

	//员工分组
	WorkerByGroup(vWorker, WorkerGruop);

	//打印每组员工信息
	PrintWorkerByGroup(WorkerGruop);
}

容器深拷贝和浅拷贝问题

#include<iostream>
#include<functional> //功能性函数头文件 "bind1st"和"bind2nd" 
#include<vector>

#include<algorithm>// 算法头文件 "for_each"头文件 

using namespace std;

class MyPrint :public binary_function<int,int,void> //仿函数
{
public:
	void operator()(int v,int value) const
	{
		cout << v <<" < "<<value<< " | ";
	}


};



//仿函数适配器 bindlst bind2nd 绑定适配器

void test()
{
	vector<int> v;
	
	for (int i = 0; i < 10; i++)
		v.push_back(i);
	MyPrint print;
	for_each(v.begin(), v.end(), bind2nd( print,100));  //"for_each" 为遍历函数 ,print 为回调函数(仿函数 )  
														//"bind2nd"绑定第二个参数,"bind1st"绑定第一个参数 
														//代码中"bind2nd"将"MyPrint"的类仿函数中的第二个参数绑定
														//同时需要仿函数继承 :public binary_function<int,int,void> 
														//第一个和第二个参数为Operator()()函数类型,void为返回函数的类型	
}

int main()
{
	test();
}

ptr_fun 函数对象适配器(将普通函数转换成函数对象)

#include<iostream>
#include<functional> //功能性函数头文件 "bind1st"和"bind2nd" 
#include<vector>

#include<algorithm>// 算法头文件 "for_each"头文件 

using namespace std;

//仿函数适配器  ptr_fun//将普通函数转换成函数对象
void print(int v1, int v2)
{
	cout << v1 + v2 << endl;
}

//类成员函数适配器 mem_fun mem_fun_ref
class Person {
public:
	Person(int age, int id):mAge(age), mId(id) {}

	void show() const
	{
		cout << " age:" <<mAge << " id:" << mId << endl;
	}

public:
	int mAge;
	int mId;
};




//仿函数适配器 bindlst bind2nd 绑定适配器

void test()
{
	//如果容器中存放的对象或者对象指针,我们 "for_each" 算法打印的时候, 调用类
	//自己提供的打印函数

	vector<Person> v;
	Person p1(10, 20);
	Person p2(41, 24);
	Person p3(13, 23);
	Person p4(11, 22);

	v.push_back(p1);
	v.push_back(p2);
	v.push_back(p3);
	v.push_back(p4);
	
	//类成员函数适配器 1、 mem_fun 2、 mem_fun_ref
	
	//格式: &类名::函数名 2、 mem_fun_ref
	for_each(v.begin(), v.end(), mem_fun_ref(&Person::show));
	cout << "________________________" << endl;
	//1、 mem_fun 使用方法
	vector<Person*>v1;
	v1.push_back(&p1);
	v1.push_back(&p2);
	v1.push_back(&p3);
	v1.push_back(&p4);

	for_each(v.begin(), v.end(), mem_fun(&Person::show));		//同样可以使用mem_fun_ref;
}

int main()
{
	test();
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值