前言
本系列内容为程序媛学习C++时做的笔记。以代码为主,并备注了打印结果以及详尽的解释注释。希望对你有所帮助。
Map
#include <iostream>
#include <map>
using namespace std;
int main() {
//map会对key进行排序(对value不会)
map<int, string> mapVar;
mapVar.insert(map<int, string>::value_type(1, "一"));
mapVar.insert(pair<int, string>(2, "二"));
mapVar.insert(make_pair(3, "三"));
//上面三种插入方式,如果key有重复就不会插入
pair<map<int, string>::iterator, bool> res = mapVar.insert(make_pair(2, "er"));
cout << "插入结果:" << res.second << endl;//插入结果:0
//mapVar[3]会对重复的key对应value进行修改。
mapVar[3] = "san";//把key=3的value值修改为san
//遍历
for (auto it = mapVar.begin(); it != mapVar.end(); it++) {
cout << it->first << "," << it->second << endl;//1,一 2,二 3,san
}
return 0;
}
根据key查找value:
map<int, string>::iterator value = mapVar.find(3);
if (value != mapVar.end()) {//找到了
cout << "找到:" << value->first << "," << value->second << endl;//找到:3,san
} else {//没找到
cout << "没找到" << endl;
}
几种迭代器:
iterator; 常规按顺序排的迭代器
const_iterator; 只读的,只能读,不能修改 的迭代器
reverse_iterator; 倒序打印的迭代器
multimap
Key会被排序,Key可以重复,重复key的数据可以分组。
几个方法:
iterator lower_bound( const Key & val);
查找一个最大的位置 it,使得 [begin( ), it) 中所有的元素的关键字都比 val 小
iterator upper_bound(const Key & val);
查找一个最小的位置 it,使得 [it, end()) 中所有的元素的关键字都比 val 大
pair < iterator, iterator > equal_range (const Key & val);
同时求得 lower_bound 和 upper_bound
multimap<int, string> mapVar;
mapVar.insert(make_pair(1, "一/1"));
mapVar.insert(make_pair(1, "一/2"));
mapVar.insert(make_pair(1, "一/3"));
mapVar.insert(make_pair(2, "二/1"));
mapVar.insert(make_pair(2, "二/2"));
mapVar.insert(make_pair(3, "三/1"));
mapVar.insert(make_pair(3, "三/2"));
for (auto it = mapVar.begin(); it != mapVar.end(); it++) {
cout << it->first << "," << it->second << endl;
}
cout << endl;
pair<multimap<int, string>::iterator, multimap<int, string>::iterator> p = mapVar.equal_range(1);
//遍历key符合的元素
for (auto iteratorVar = p.first; iteratorVar != p.second; iteratorVar++) {
cout << iteratorVar->first << "," << iteratorVar->second << endl;
}
打印:
1,一/1
1,一/2
1,一/3
2,二/1
2,二/2
3,三/1
3,三/2
1,一/1
1,一/2
1,一/3
预定义函数
#include <iostream>
using namespace std;
int main() {
//"a"+"b";字符串不让相加,这样写报错。但C++提供了预定义函数如:
//intPlus,minus,multiplies,divides,modulus ...
//举例“+”可用plus
plus<int> intPlus;//不可以这样写:intPlus<int> intPlus(1,2);这样写是调用的构造方法
//调用重载的括号运算符。
cout << intPlus(1, 2) << endl;//3
plus<string> strPlus;
cout << strPlus("一", "二") << endl;//一二
plus<float> fPlus;
cout << fPlus(1.1f, 3.5f) << endl;//4.6
return 0;
}
手写预定义函数
template<typename T>//结构体上声明模板
struct plusC {//不用struct,写成这样也可以:class plusC { public:
T operator()(const T &x, const T &y) {//重载()运算符
return x + y;
}
};
调用:
plusC<string> c;
//调用重载的括号运算符
cout << c("a", "b") << endl;//ab
对象存入到容器后,对象的生命周期/状态
class Person {
private:
string name;
public:
Person(string name) : name(name) {}
void setName(string name) {
this->name = name;
}
string getName() {
return this->name;
}
Person(const Person &person) {
this->name = person.name; // 浅拷贝
cout << "Person拷贝构造函数执行了..." << endl;
}
~Person() {
cout << "Person析构函数执行了" << endl;
}
};
int main() {
// Java:把对象存入 添加到 集合
// C++: 调用拷贝构造函数,存进去的是另一个新的对象
vector<Person> vectorVar;
// person 被main函数弹栈 析构一次
Person person("S");
// 里面的insert函数弹栈 析构一次
vectorVar.insert(vectorVar.begin(), person); // 外面的person是旧地址,到insert函数里面的person就是新地址(拷贝构造函数 一次)
person.setName("HL");
// newPerson 被main函数弹栈 析构一次
Person newPerson =
vectorVar.front(); // front里面的person是旧地址, 外面的newPerson就是新地址(拷贝构造函数 一次)
cout << "newPerson:" << newPerson.getName().c_str() << endl;
// 3次析构函数 两次拷贝构造
return 0;
} // main弹栈
谓词(仿函数)
为什么谓词叫仿函数?
因为调用结构体重载的()运算符,很像调用一个函数。如下:
struct Object {
void operator()() {//重载()运算符
cout << "仿函数" << endl;
}
};
void f2() {
cout << "普通函数" << endl;
}
//调用
Object f;
f();//打印:仿函数
f2();//打印:普通函数
实现for_each打印
回调函数方式:
#include <iostream>
#include "set";
#include "algorithm";//for_each是算法包的
using namespace std;
void method(string str) {
cout << "自定义打印:" << str << endl;
}
int main() {
set<string> s;
s.insert("Q");
s.insert("W");
s.insert("E");
for_each(s.begin(), s.end(), method);
return 0;
}
输出:
自定义打印:E
自定义打印:Q
自定义打印:W
仿函数方式:
可以实现打印次数的统计。
class showAction {
public:
int count = 0;
void operator()(string str) {//一元谓词(因为只一个入参,两个入参叫二元谓词)
cout << "打印:" << str << endl;
count++;
}
};
int main() {
set<string> s;
s.insert("Q");
s.insert("W");
s.insert("E");
showAction show;
//不是show(),没有();也不能直接写showAction(),showAction()是调用的无参构造函数。
show = for_each(s.begin(), s.end(), show);//传入进去的show的新副本,我们外面的show是旧地址
cout << "统计次数:" << show.count << endl;//统计次数:3
return 0;
}
打印:
打印:E
打印:Q
打印:W
统计次数:3
附for_each源码:
stl_algo.h
/**
* @param __f A unary function object.(一元函数对象。)
*/
template<typename _InputIterator, typename _Function>
_Function
for_each(_InputIterator __first, _InputIterator __last, _Function __f)
{
// concept requirements
__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
__glibcxx_requires_valid_range(__first, __last);
for (; __first != __last; ++__first)
__f(*__first);
return _GLIBCXX_MOVE(__f);
}