12 2022 档案
摘要:#include <> 和 #include "" 的区别 1.#include <> 引用的头文件应当是编译器中的类库目录下的头文件。 2.#include "" 引用的头文件是程序目录下的头文件。 3.如果#include "" 中引用的文件在程序目录下未能找到,将从编译器中的类库目录下继续找。
阅读全文
摘要:unique_ptr的成员函数在上一篇博客中几乎全部涵盖,其实还有一个很有踢掉,即std::unique_ptr::get_deleter字面已经很明显了,就获得deleter 智能指针采通过引用计数我们能解决多次释放同一块内存空间的问题,并且和之间直接移交管理权的方式比较这种方式更加灵活安全。 但
阅读全文
摘要:关联容器 无序关联容器->链式哈希表 增删查 O(1) set:集合key map:映射表[key,value] unordered_set 单重集合 不允许重复 unordered_multiset 多重集合 unordered_map 单重映射表 unordered_multimap 多重映射表
阅读全文
摘要:函数对象 =》C语言中的函数指针 函数对象 尽管函数指针被广泛用于实现函数回调,但C++还提供了一个重要的实现回调函数的方法,那就是函数对象。函数对象(也称“函数符”)是重载了“()”操作符的普通类对象。因此从语法上讲,函数对象与普通的函数行为类似。 用函数对象代替函数指针有几个优点: 首先,因为对
阅读全文
摘要:标准容器->容器适配器 什么叫适配器? 1:适配器底层没有自己的数据结构,它是另外一个容器的封装,它的方法, 全部由底层依赖的容器进行实现的.像标准库中的stack 如下图 2:没有实现自己的迭代器 容器适配器 stack,queue,priotity_queue 没有迭代器 stacks1; 栈,
阅读全文
摘要:泛型算法 头文件 包含了C++ STL里面的泛型算法 泛型算法=》template + 迭代器 + 函数对象 sort, find , find_if , binary_search , for_each 泛型算法特点 1:泛型算法的参数接收的都是迭代器(迭代器保证了接口统一) 2:泛型算法的参数还
阅读全文
摘要:无序关联容器 #include <unordered_set> #include <unordered_map> 有序关联容器 => 底层是红黑树结构 #include<set> #include<map> set<int> set1 ;//不允许重复 for(int i=0;i<100;i++){
阅读全文
摘要:容器迭代器 Vector vec; for(int i=0;i<100;i++){ vec.push_back(i); } const_iterator 常量迭代器 (基类) iterator 普通迭代器 (子类) iterator 是继承自const_iterator的 class const_i
阅读全文
摘要:vector和deque之间的区别? vector:底层动态数组,内存连续,二倍方式扩容 vector vec;默认是没有开辟空间的, 0->1->2->4->8->16 可以用reserve(20) 只开辟空间,没有放置元素 deque:动态开辟的二维数组空间,第二维是固定长度的空间,扩容的时候,
阅读全文
摘要:deque:双端队列容器(队头队尾都可入,出) 底层数据结构情况 动态开辟的二维数组,一维数组从2开始,以2倍方式进行扩容,每次扩容后,原来第二维数组 从新的第一维数组的下标oldsize/2 开始存储 如下列图序 满了扩容,扩容第1维,2倍扩 deque deq; 增加: deq.push_bac
阅读全文
摘要:STL (standard template libaray - 标准模板库):是 C++ 标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。 通俗来说:STL就是将常见的数据结构(例如 顺序表,链表,栈,队列,二叉树,哈希...)以模板的形式进行封装,使用时,
阅读全文
摘要:底层数据结构:动态开辟的数组,每次以原始空间2倍扩容 vector vec; 增加 vec.push_back(100);容器末尾加元素 时间负责度O(1) 可能导致容器扩容 容器中的,对象的构造析构,内存的开辟释放,通过什么来实现? 容器的空间配置器allocator allocate deall
阅读全文
摘要:unique_lock condition_variable 1:lock_guard 和 unique_lock 2:condition_variable wait 和 notify_all 方式1 std::mutex mtx; mtx.lock(); .. ... mtx.unlock();/
阅读全文
摘要:C++11多线程类库中提供了 include包含了很多原子类型 原子操作 若干汇编指令具有读-修改-写类型,也就是说它们访问存储器单元两次,第一次读原值,第二次写新值 假定运行在两个cpu上的两个内核控制路径试图通过执行非原子操作来同时读-修改-写同一个存储器。 首先两个cpu都试图读同一单元,然后
阅读全文
摘要:多线程编程两个问题 1:线程互斥问题 竞态条件->临界区代码段->原子操作->互斥锁mutex 2:线程间的同步通信 生产者,消费者 线程模型 #include <iostream> #include <queue> #include <thread> #include <mutex> #inclu
阅读全文
摘要:多线程程序 竞态条件:多线程程序执行的结果是一致的,不会随着CPU对线程不同的调用顺序而产生不同的运行结果. 解决?:互斥锁 mutex 经典的卖票问题,三个线程卖100张票 代码1 #include <iostream> #include <thread> #include <list> #inc
阅读全文
摘要:C++语言层面多线程=>好处:跨平台 windows/linux thread/mutex/condition_variable lock_gurad/unique_lock atomic/原子类型,基于CAS操作的原子类型 线程安全的 睡眠sleep_for C++ thread => windo
阅读全文
摘要:既然lambda表达式只能使用在语句中,如果想跨语句使用之前定义好的lambda表达式,怎么办?用什么类型来表示lambda表达式? 用function类型来表示函数对象类型 bind1st/bind2nd bind 绑定器返回的都是 函数对象 lambda表达式=>函数对象 示例1 map<int
阅读全文
摘要:C++11 函数对象的升级版=>lambda表达式 函数对象的缺点: 使用在泛型算法,参数传递, 比较性质/自定义操作 优先级队列, 需要专门定义出一个类 //lambda表达式语法: //[捕获外部变量](形参列表)->返回值{操作代码} auto func1=[]()->void{cout<<"
阅读全文
摘要:bind1st和bind2nd只能用于二元函数对象 c++11 bind绑定器 返回的结果还是个函数对象 std::bind函数定义在头文件functional中,是一个函数模板,它就像一个函数适配器,接受一个可调用对象(callable object),生成一个新的可调用对象来“适应”原对象的参数
阅读全文
摘要:类模版std::function是一种通用、多态的函数封装。std::function的实例可以对任何可以调用的目标实体进行存储、复制、和调用操作,这些目标实体包括普通函数、Lambda表达式、函数指针、以及其它函数对象等。std::function对象是对C++中现有的可调用实体的一种类型安全的包
阅读全文
摘要:std::function是一组函数对象包装类的模板,实现了一个泛型的回调机制。function与函数指针比较相似,优点在于它允许用户在目标的实现上拥有更大的弹性,即目标既可以是普通函数,也可以是函数对象和类的成员函数,而且可以给函数添加状态。 声明一个function时,需要给出所包装的函数对象的
阅读全文
摘要:模板作为C++泛型编程的基础十分重要,其使得一份代码能用于处理多种数据类型。而有些时候,我们会希望对一些特定的数据类型执行不同的代码,这时就需要使用模板特例化(template specialization)。 函数模板特例化 首先函数模板的特例化并不是函数重载,每一个特例化实际上是提供了另一个模板
阅读全文
摘要:自己实现绑定器,代码如下 #include <iostream> #include <vector> #include <string> #include <algorithm> #include <functional> #include <ctime> using namespace std;
阅读全文
摘要:bind用于绑定可调用 (Callable) 对象(函数对象、指向函数指针、到函数引用、指向成员函数指针或指向数据成员指针)和其参数。返回值为绑定成功后的函数对象 C++11中引入的function机制,其中绑定器主要有三种:bind1st、bind2nd、bind(C++11) 函数对象 尽管函数
阅读全文
摘要:代码1 #include <iostream> #include <thread> using namespace std; class A { public: A() { cout << "A()" << endl; } ~A() { cout << "~A()" << endl; } void
阅读全文
摘要:代码1 int main(){ //裸指针,手动开辟,需要自己释放,如果忘记了或者因为 //程序逻辑导致p没有释放,那么就会导致内存泄漏 int *p=new int(10); if(***){ retur -1; } delete p; return 0; } 有没有什么办法帮我们管理指针,确保资
阅读全文
摘要:代码1 #include <iostream> #include <functional> #include<cstdio> #include<cstring> using namespace std; class MyString3 { public: MyString3(const char *
阅读全文
摘要:代码1 using namespace std; class TestV2 { public: TestV2(int a = 10) : ma(a) { cout << "TestV2(int) " << ma <<" 对象地址="<<this << endl; } ~TestV2() { cout
阅读全文
摘要:代码1 #include <iostream> using namepspace std; class Test { public: Test(int a=10):ma(a){cout<<"Test()"<<endl;} ~Test(){cout<<"~Test()"<<endl;} Test(co
阅读全文