C++高性能并行编程与优化 - 课件 - 02 现代 C++ 入门:RAII 内存管理p 的 某个成员函数而已,并没有接过掌管对象 生命周期的大权。 解决方案 2 : unique_ptr 不能拷贝,但可以移动 • 第二种是,你的 func() 需要“夺走”资源的 占有权。比如右边这个例子, func 把指针 放到一个全局的列表里, p 的生命周期将 会变得和 objlist 一样长。因此需要接过掌 管对象生命周期的大权。 • 请根据你的具体情况,决定要选用哪一种 解决方案:提前获取原始指针 • 最简单的办法是,在移交控制权给 func 前,提前通过 p.get() 获取原始指针: 解决方案:提前获取原始指针(续) • 不过你得保证 raw_p 的存在时间不超过 p 的生命周期,否则会出现危险的空悬指 针。比如右边这样: 更智能的指针: shared_ptr • 使用起来很困难的原因,在于 unique_ptr 解决重复释放 的方式是禁止拷贝,这样虽然有效率高的优势,但导致使 放时。比如:指向窗口中上一次被点击的元素。 5. 初学者可以多用 shared_ptr 和 weak_ptr 的组合,更安全。 shared_ptr 管理的对象生命周期,取决于所有引用中,最长寿的那一个。 unique_ptr 管理的对象生命周期长度,取决于他所属的唯一一个引用的寿命 。 那是不是只要 shared_ptr 就行,不用 unique_ptr 了? • 可以适当使用减轻初学者的压力,因为他的行为和0 码力 | 96 页 | 16.28 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 13 C++ STL 容器全解之 vector存,就不必手动释放了,更安 全。 https://github.com/zenustech/zeno/blob/master/zenovis/src/Scene.cpp vector 容器:生命周期由主对象管理 • C++ 中哪个运算符是最强的?我觉得是 } • 因为 } 标志着一个语句块的结束,在这里,他 会调用所有身处其中的对象的解构函数。比如 这里的 vector ,他的解构函数会释放动态数组 都会失效。 因此如果你是在语句块内获取的 data() 指针, 语句块外就无法访问了。 • 可见 data() 指针是对 vector 的一种引用,实 际对象生命周期仍由 vector 类本身管理。 vector 容器:延续生命周期 • 如果需要在一个语句块外仍然保持 data() 对 数组的弱引用有效,可以把语句块内的 vector 对象移动到外面的一个 vector 对象 上。 变成空数组, a 指向原来 b 所包 含的元素数组,且地址不变。 • 之后即使不直接使用外面的那个临时对象 a , 也可以继续通过 data() 指针来访问数据。 vector 容器:延续生命周期 • 也可以移动到一个全局变量的 vector 对象。 • 这样数组就会一直等到 main 退出了才释放。 • 小彭老师曾经在 taichi 中就是用了一个全局 变量伺候了 unique_ptr0 码力 | 90 页 | 4.93 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 15 C++ 系列课:字符与字符串6. 通过实战案例来学习 STL 算法库 7. C++ 标准输入输出流 & 字符串格式化 8. traits 技术,用户自定义迭代器与算法 9. allocator ,内存管理与对象生命周期 ASCII 码 第 1 章 计算机如何表达字符 https://zh.wikipedia.org/wiki/ASCII 计算机如何表达字符 • 众所周知,计算机只能处理二进制 整数,字符要怎么办呢? string_view 和 span 无非是个弱引用版本,额外增加了在头部切片的能力而 已。 强引用胖指针: string • 刚刚说的 string 容器,是掌握着字符串生命周期( lifespan )的胖指针。 • 这种掌管了所指向对象生命周期的指针称为强引用( strong reference )。 • 这个强引用的强,体现在哪里? • 当 string 容器被拷贝时,其指向的字符串也会被拷贝(深拷贝)。 string_view ,这种弱引用( weak reference )不影响原对象的生命周期,原对象的销毁仍然由强引用控制。 • 这个弱引用的弱,体现在哪里? • 当 string_view 被拷贝时,其指向的字符串仍然是同一个(浅拷贝)。 • 当 string_view 被销毁时,其指向的字符串仍存在(弱引用不影响生命周期) 。 s1 s2 “ 具体字符 串” “ 具体字符 串” 拷贝0 码力 | 162 页 | 40.20 MB | 1 年前3
现代C++ 教程:高速上手C++11/14/17/20会将 foo 局部返回的值进行移动。也就是 后面我们将会提到的移动语义。 右值引用和左值引用 要拿到一个将亡值,就需要用到右值引用:T &&,其中 T 是类型。右值引用的声明让这个临时值的 生命周期得以延长、只要变量还活着,那么将亡值将继续存活。 C++11 提供了 std::move 这个方法将左值参数无条件的转换为右值,有了它我们就能够方便的获 得一个右值临时对象,例如: #include + lv1; // 合法, 常量左值引用能够延长临时变量的生命周期 // lv2 += "Test"; // 非法, 常量引用无法被修改 std::cout << lv2 << std::endl; // string,string, std::string&& rv2 = lv1 + lv2; // 合法, 右值引用延长临时对象生命周期 rv2 += "Test"; // 合法, 非常量引用能够修改临时变量 在上面的代码中: 1. 首先会在 return_rvalue 内部构造两个 A 对象,于是获得两个构造函数的输出; 2. 函数返回后,产生一个将亡值,被 A 的移动构造(A(A&&))引用,从而延长生命周期,并将这个右 值中的指针拿到,保存到了 obj 中,而将亡值的指针被设置为 nullptr,防止了这块内存区域被销 毁。 从而避免了无意义的拷贝构造,加强了性能。再来看看涉及标准库的例子:0 码力 | 83 页 | 2.42 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 05 C++11 开始的多线程编程分离该 线程——意味着线程的生命周期不再由当 前 std::thread 对象管理,而是在线程退 出以后自动销毁自己。 • 不过这样还是会在进程退出时候自动退出 。 解构函数不再销毁线程:移动到全局线程池 • 但是 detach 的问题是进程退出时候不会 等待所有子线程执行完毕。所以另一种解 法是把 t1 对象移动到一个全局变量去, 从而延长其生命周期到 myfunc 函数体外0 码力 | 79 页 | 14.11 MB | 1 年前3
面向亿行 C/C++ 代码的静态分析系统设计及实践-肖枭关键步骤高亮和行为解释 配套完善的文档 代码交叉索引 降低感知误报率 回忆下代码评审 时最不能忍的事 是啥?对,就是 不能像在IDE里 面一样查看符号 定义使用。 代码交叉索引 方法4:Bug生命周期跟踪 精确查找类似Bug,利用 标记数据排除潜在误报 通过修复率等参数对分析 器进行综合评价 降低感知误报率 方法5:防止误标和作弊 标记量,间隔时间,标记内容 用基线数据训练模型0 码力 | 39 页 | 6.88 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 03 现代 C++ 进阶:模板元编程捕获的是引用,是 fac 的地 址,而 make_twice 已经返回了,导致 fac 的引用变成了内存中一块已经失效的 地址。 • 总之,如果用 [&] ,请保证 lambda 对象 的生命周期不超过他捕获的所有引用的寿 命。 作为返回值:解决问题 • 这时,我们可以用 [=] 来捕获,他会捕 获 fac 的值而不是引用。 • [=] 会给每一个引用了的变量做一份拷贝 ,放在0 码力 | 82 页 | 12.15 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 14 C++ 标准库系列课 - 你所不知道的 set 容器表达式知多少 6. 通过实战案例来学习 STL 算法库 7. C++ 标准输入输出流 & 字符串格式化 8. traits 技术,用户自定义迭代器与算法 9. allocator ,内存管理与对象生命周期 set 和 vector 的区别 • 都是能存储一连串数据的容器 。 • 区别 1 : set 会自动给其中的 元素从小到大排序,而 vector 会保持插入时的顺序。 • 区别 20 码力 | 83 页 | 10.23 MB | 1 年前3
C++高性能并行编程与优化 - 课件 - 17 由浅入深学习 map 容器表达式知多少 6. 通过实战案例来学习 STL 算法库 7. C++ 标准输入输出流 & 字符串格式化 8. traits 技术,用户自定义迭代器与算法 9. allocator ,内存管理与对象生命周期 10. C++ 异常处理机制的前世今生 我们都要认真鞋习哦 我们都要认真鞋习哦 第一章:读取与写入 我负责监督你鞋习 ! 我负责监督你鞋习 ! map 查找元素的两个接口 • map 提供了两个查找元素的接口,一曰0 码力 | 90 页 | 8.76 MB | 1 年前3
《深入浅出MFC》2/e.); (in DefWindowProc) WM_QUIT WM_CLOSE WM_CREATE WM_DESTROY 1 6 5 8 2 3 7 图 1- 5 窗口的生命周期(详细说明请看图 1- 6) 26 1. 程序初始化过程中调用CreateWindow,为程序建立了一个窗口,做为程序的萤 幕舞台。CreateWindow 产生窗口之后会送出WM_CREATE 的标准反应是调用PostQuitMessage。 8. PostQuitMessage 没什么其它动作,就只送出WM_QUIT 消息,准备让消息循 环中的GetMessage 取得,如步骤2,结束消息循环。 图1-6 窗口的生命周期( 请对照图1-5) 为什么结束一个程序复杂如斯?因为操作系统与应用程序职司不同,二者是互相合作的 关系,所以必需各做各的份内事,并互以消息通知对方。如果不依据这个游戏规则,可 能就会有麻烦0 码力 | 1009 页 | 11.08 MB | 1 年前3
共 10 条
- 1













