NDK-029: C++10:STL函数对象和谓词
2025-01-14 本文已影响0人
xqiiitan
29.C++进阶 - STL函数对象和谓词
C++文档 http://en.cppreference.com/w/c
1.map容器
map会对key 进行排序
添加数据方式的区别,前面三种,key重复时,数据插入 不生效(后面的插入不会生效)。
第四种插入方式,会覆盖写入。
如果要判断是否添加成功,如何处理?参考Day28内容。insert有返回值pair。
map会根据key,进行数据排序,里面使用二叉树算法。
#include <map>
#include <iostream>
using namespace std;
void main() {
map<int, string> map1;
// 数据添加的几种方式
map1.insert(pair<int, string>(01, "01"));
map1.insert(make_pair(02, "02"));
map1.insert(map<int, string>::value_type(03,"03"));
map1[04]= "04"; // 常用的添加方式: map1[key]=value
// 遍历-迭代器
for(map<int,string>::iterator it=map1.begin(); it!=map1.end(); it++){
cout << it->first <<"~" << (it->second).c_str() << endl;
}
// 删除,查找
map<int,string>::iterator find_it = map1.find(100);
if(find_it != map1.end()){
// 找到
cout << find_it->first << endl;
} else{
// 找不到
}
}
2.multimap容器介绍
允许key键重复的容器, 根据key就行排序。
void main() {
multimap<int, string> map1;
// 1班:11,12,13, 2班:21,22,23 三班:31,32,33
map1.insert(pair<int,string>(1,"11"));
map1.insert(pair<int,string>(1,"12"));
map1.insert(pair<int,string>(1,"13"));
map1.insert(pair<int,string>(2,"21"));
map1.insert(pair<int,string>(2,"22"));
map1.insert(pair<int,string>(2,"23"));
map1.insert(pair<int,string>(3,"31"));
map1.insert(pair<int,string>(3,"32"));
map1.insert(pair<int,string>(3,"33"));
for(map<int,string>::iterator it=map1.begin(); it!=map1.end(); it++){
cout << it->first <<"~" << (it->second).c_str() << endl;
}
cout << "----------------" << endl;
// 分组查询,每组多个数据
multimap<int,string>::iterator find_it = map1.find(1);
while(find_it != map1.end()) {
cout << it->first << "~" << (it->second).c_str() << endl;
find_it++;
if(find_it==map1.end() || find_it->first !=1) { // 不是目标分组
break;
}
}
}
3.容器对象- 拷贝构造函数
java中会把对象添加到集合中;
C++中会调用对象的 拷贝构造函数,存进去的是另一个对象。
注意:如果想要存同一个对象,在任何地方改变,集合的数据也相应的发生变化,
就可以用指针,存储的时候存 指针。
class Person {
public: string name;
char *test;
public:
Person(){} // 默认构造函数
Person(string name){this->name = name;}
Person(const Person& person) {
cout << "拷贝构造函数" << endl;
this->name = person.name;
test = (char*) malloc(10);
}
~Person() {
// 释放malloc申请的内存
free(test);
cout << "析构函数"<< endl;
}
public:
void setName(string name) {this->name =name;}
}
void main() {
// 第一个错误:没有默认的构造函数
// 第二个错误:西沟函数也可能回调多次,如果在析构函数中释放了内存,需要在拷贝构造函数中就行深拷贝。
// 避免被反复析构同一片内存。 导致宕机。
vector<Person> vector1;
Person person("Darren");
vector1.push_back(person); // 调用对象的拷贝构造函数,传入的不是person对象。
person.setName("Jack");
Person person1 = vector.front(); // 调用拷贝构造函数
cout << person1.name.c_str() << endl;
}
析构函数也可能回调多次,如果在析构函数中释放了内存,需要在拷贝构造函数中就行深拷贝。
不能直接地址赋值。
4.函数对象(仿函数) 一元谓词/二元谓词
谓词:遵循一定规律,做回调用的,
一元谓词:一个参数的。
二元谓词:两个参数的。
class Compare {
public:
void operator()(){
cout << "仿函数" << endl;
}
}
void compare1() {
cout << "普通函数" << endl;
}
void main() {
Compare compare;
compare(); // 跟函数类似,所以叫仿函数。
compare1();
}
// 谓词
#include <iostream>
#include <set>
#include <algorithm> // 预定义函数,已实现好的算法 for_each
using namespace std;
// 一元谓词,回调函数
void print(int number) {
cout << number << endl;
}
// 仿函数:一元谓词函数
class PrintObj {
public:
int count=0;
public:
void operator()(int number){
cout << number << endl;
count++;
}
}
// 回调函数与仿函数的区别。
仿函数,可以添加count,记录一些东西。
void main(){
set<int > set1; // set<int, PrintObj> set1; 这边可以不要括号。
set1.insert(1);
set1.insert(2);
set1.insert(3);
set1.insert(4);
// 一元谓词。
// for_each(set1.begin(), set1.end(), print);
// for_each(str1.begin(), str1.end(), PrintObj()); // 回调函数
// 仿函数如果要保存记录状态,要确保对象一致。可以用返回值。
PrintObj printObj;
printObj = for_each(str1.begin(), str1.end(), printObj);
cout << "count个数:"<< printObj.count << endl;
}
二元谓词
// 仿函数(它不是函数,是一个对象,只不过有点像函数): 二元谓词
class CompareObj{
public:
bool operator()(cosnt string str1,const string str2){//2个参数。
return str1 > str2;
}
}
void main(){
// 传入二元谓词的仿函数
set<string, CompareObj> set1;
set1.insert("aaa");
set1.insert("aAa");
set1.insert("CCC");
set1.insert("ddd");
// 遍历输出
for(set<string>::iterator it=str1.begin(); it!=str1.end(); it++){
cout<< (*it).c_str() << endl;
}
// 是否包含aaa,可以遍历比较,
/* vector<string>::iterator find_it =find_if(vector1.begin(),vector1.end(), CompareObj());
if(find_it !=vector1.end()) {
// 找到了
} else {
// 没找到
}*/
}