C++学习笔记 入门篇-8

前言

本系列内容为程序媛学习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);
   }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值