├── README.md ├── doc ├── C++20新特性.png ├── C++入门知识点.png ├── C++必备知识点.png ├── C++的坑.png ├── MoreCppIdioms.pdf ├── c++学习路线图.png ├── profiling_tools.pdf └── 程序喵大人学习宝典第一版.pdf ├── img ├── cxmdr.jpg └── wechat.jpg └── src ├── test_multi_array.cc ├── test_shared_ptr.cc ├── test_unique_ptr.cc └── variant ├── test_variant_index.cc ├── test_variant_monostate.cc ├── test_variant_polymorphism.cc ├── test_variant_visit.cc └── test_why_variant.cc /README.md: -------------------------------------------------------------------------------- 1 | # C++学习 2 | 3 | 致力于搭建一个最好的C++学习平台。 4 | 5 | **很多人不知道是否应该入坑C++** 6 | **很多人不知道如何准备C++面试** 7 | **很多人不知道如何入门C++** 8 | **很多人不知道如何进阶C++** 9 | 10 | 11 | 这些人可以来这里看看!**如果大家有学习资源推荐,欢迎提MR**。 12 | 13 | **欢迎大家的批评指正,但不接受喷子,感谢支持,如果大家觉得不错,求给个star!** 14 | 15 | **如果阅读时,发现错误,或者其它任何问题可以提issue** 16 | 17 | 另外大家也可以关注我的**公众号:程序喵大人**,以后所有文章都会首发在公众号上,下面是公众号二维码,谢谢大家支持。 18 |
19 | 20 | 我也特意为大家整理了一些文档和脑图,详见doc目录。 21 | ## 干货 22 | 23 | ### 入门必备 24 | 25 | #### 基础 26 | 27 | - [入门可以首先看清华郑莉老师视频](https://space.bilibili.com/702528832) 28 | 29 | - [C++学习路线](https://mp.weixin.qq.com/s/poq9aDdEL5kLM5sjSqJ72A) 30 | 31 | - [C++服务端学习路线](https://mp.weixin.qq.com/s/6qTLqEU5JuxBo0wHjBWG0Q) 32 | 33 | - [C++就业方向](https://mp.weixin.qq.com/s/GDBqvRTuaMg8WPaTTsFbmg) 34 | 35 | - [如何入门C++](https://mp.weixin.qq.com/s/koqsBzRSjh_M5GrI-WZhgw) 36 | 37 | - [学习C++应该做点什么项目](https://mp.weixin.qq.com/s/DLQllBnFyA6vt2aFENP-2Q) 38 | 39 | - [C++基础知识汇总](https://mp.weixin.qq.com/s/eYLJ0pzSQjOfXgDsXL0p0w) 40 | 41 | - [C++面试宝典](https://mp.weixin.qq.com/s/qhFERQ1odNkgZS0PkHm1EA) 42 | 43 | - [数组长度可以为变量吗?](https://blog.csdn.net/qq_29426201/article/details/106342991) 44 | 45 | - [是否应该使用异常处理](https://mp.weixin.qq.com/s/BIaz2Vbf3HyjEDTM9abSAg) 46 | 47 | - [new/delete、new[]/delete[]为什么需要配对使用](https://mp.weixin.qq.com/s/5vFess8NxQdUwsvtrWs8WA) 48 | 49 | - [指针和引用的区别以及使用场景](https://mp.weixin.qq.com/s/f9KQ1eNGGSY2Lqv9JM4UVQ) 50 | 51 | - [C++对象布局分析](https://mp.weixin.qq.com/s/sufz7wxC_rwc1q3FXY-QMQ) 52 | 53 | - [C++为什么要入这4种类型转换?](https://mp.weixin.qq.com/s/6YW7VX787X7kZiRBLbVn-Q) 54 | 55 | - [为什么会出现nullptr?](https://mp.weixin.qq.com/s/dov9ofXoJTX8rEa9asTZuQ) 56 | 57 | - [非常全面的时间相关所有函数使用](https://mp.weixin.qq.com/s/0W8JBokXk0vPlAtkd2sFPQ) 58 | 59 | - [C++编码规范](https://mp.weixin.qq.com/s/ulSr2GUc1pJf09LxnwTTqQ) 60 | 61 | - [sqlite3使用教程](https://mp.weixin.qq.com/s/xrIxe9JE7uNzir0c8i1tsQ) 62 | 63 | - [如何学好C++?](https://mp.weixin.qq.com/s/VJc_pIdYjmvU1t7W0zTpBA) 64 | 65 | - [volatile关键字解析](https://mp.weixin.qq.com/s/6rkCEBuFjUHERk9RmeWLbQ) 66 | 67 | - [C++避坑指南](https://mp.weixin.qq.com/s/7PolqHz6IH1wuZTXKPU_xg) 68 | 69 | - [字符串split方法实现](https://mp.weixin.qq.com/s/LdiMuhY0IDFCP8V1dPxg-g) 70 | 71 | - [RTTI知识点](https://mp.weixin.qq.com/s/vzuU0qRRsD-aLuWxMTXA_g) 72 | 73 | - [C++匠心之作从0到1入门资料](https://github.com/AnkerLeng/Cpp-0-1-Resource) 74 | 75 | #### C++11 新特性 76 | 77 | - [auto&decltype知识点](https://mp.weixin.qq.com/s/3BQ2JlVQsE0sm6eDNa5AdA) 78 | 79 | - [左值、右值、左值引用、右值引用、移动语义、完美转发](https://mp.weixin.qq.com/s/aCv7vIyrGyqu06QpNjZFTA) 80 | 81 | - [C++11列表初始化](https://mp.weixin.qq.com/s/wpV4K0aJS9l3ilk4nuurQA) 82 | 83 | - [std::function和lambda表达式](https://mp.weixin.qq.com/s/6zzF8GEgpMsNrdoBLi5csA) 84 | 85 | - [C++11的模板改进](https://mp.weixin.qq.com/s/bnu46tUodqxKLfLJ5Zxd0A) 86 | 87 | - [智能指针](https://mp.weixin.qq.com/s/Aujdxj3k_apNwW9Cnd3_eg) 88 | 89 | - [线程相关所有知识点](https://mp.weixin.qq.com/s/rPjRTOTYK2SGr6WxgWI_Vg) 90 | 91 | - [C++11新特性的所有知识点](https://mp.weixin.qq.com/s/kAH-402oYgAa3GAVgJ8EaQ) 92 | 93 | #### C++14 新特性 94 | 95 | - [C++14新特性的所有知识点](https://mp.weixin.qq.com/s/xeeOfusRDSUQQyplUA-o7g) 96 | 97 | #### C++17 新特性 98 | 99 | - [C++17新特性的所有知识点](https://mp.weixin.qq.com/s/6FcCfFWHwcmywPuemyxHng) 100 | 101 | - [variant实现多态](https://mp.weixin.qq.com/s/bTFbunrSLnOtyCSJEZwR3A) 102 | 103 | #### C++20 新特性 104 | 105 | - [C++20新特性指南](https://mp.weixin.qq.com/s/TSnN9QRyqZsa8i9-KKKDpQ) 106 | 107 | - [latch、barrier、semaphore](https://mp.weixin.qq.com/s/5VFXzsaxwLJumCvMtbVHJg) 108 | 109 | #### 常用的新特性 110 | 111 | - [我常用的C++新特性](https://mp.weixin.qq.com/s?__biz=MzkyODE5NjU2Mw==&mid=2247486826&idx=1&sn=6c9779db19fb28585aceb904878d203b&chksm=c21d3fd6f56ab6c0e3ef5ab39d67006942e30d8bd2607a1023d23db7e7dff97796e1ab288d8f&token=1242239139&lang=zh_CN#rd) 112 | 113 | #### 必备技能 114 | 115 | - [如何写简历](https://mp.weixin.qq.com/s/JBVR4W4cyd3xVvF6dAEF4g) 116 | 117 | - [程序员必备技能](https://mp.weixin.qq.com/s/IVdtn_9DQXO0a3pn_jHhaA) 118 | 119 | - [如何适应新环境](https://mp.weixin.qq.com/s/jJsUf9YfzVMGIVk2AwKNTA) 120 | 121 | - [大佬的经验之谈](https://mp.weixin.qq.com/s/1PpbVTu9Dt3Zr4YuDpC_uQ) 122 | 123 | 124 | ### 进阶必备 125 | 126 | #### 常识 127 | 128 | - [条件变量有个坑需要注意](https://mp.weixin.qq.com/s/gqq6TZCNabI3qvejzqFcGQ) 129 | 130 | - [为什么都说虚函数慢?](https://mp.weixin.qq.com/s/eIS8kjPT6R_uQMqLwKSXDQ) 131 | 132 | - [C++内存管理全景指南](https://mp.weixin.qq.com/s/GGoPUZjgmGPewATL_QuJSA) 133 | 134 | - [编译器如何实现的lambda表达式](https://mp.weixin.qq.com/s/L0tAA9tGdL2i8K-iO7UusQ) 135 | 136 | - [普通的int main(){}没有写return 0会怎么样?](https://mp.weixin.qq.com/s/k3i7MW28UVtr86RU51-KuQ) 137 | 138 | - [为什么空类大小是1](https://mp.weixin.qq.com/s/uatF3kF7SRQ-zLpXSoYeyg) 139 | 140 | - [SDK开发的一些思考](https://mp.weixin.qq.com/s/DmWTD8ve0pfomy4pl4O43Q) 141 | 142 | - [软件开发的建议](https://mp.weixin.qq.com/s/2sgLPjyujNrO8fgsTRTPDA) 143 | 144 | - [模板定义一定要写在头文件中吗](https://mp.weixin.qq.com/s/49rziyP5XICMn16vFcK_ew) 145 | 146 | - [折叠表达式知识点](https://mp.weixin.qq.com/s/0BTD8w_doWXBsHx6ij72jg) 147 | 148 | - [cout vs printf](https://mp.weixin.qq.com/s/wAS1Xk4IsGmBggg4WiBaIw) 149 | 150 | - [async的两个坑](https://mp.weixin.qq.com/s/lNct6HRknCNL9X9DAZjCBg) 151 | 152 | - [const重载](https://mp.weixin.qq.com/s/xsMwv1hR31YqquPFB4oTWw) 153 | 154 | - [优雅的实现多维数组](https://mp.weixin.qq.com/s/Lz7pC-0DF0PtBnULBw-Gqw) 155 | 156 | - [推荐资料:更多C++编程技法](https://upload.wikimedia.org/wikipedia/commons/5/55/MoreCppIdioms.pdf) 157 | 158 | #### 源码分析 159 | 160 | - [源码分析string的实现](https://mp.weixin.qq.com/s/jnYQ_TRqe8otOhST8Pesww) 161 | 162 | - [源码分析shared_ptr的实现](https://mp.weixin.qq.com/s/rx5QvFHCacC7SHtXlV_C8w) 163 | 164 | - [分析STL的基础能力:type_traits](https://mp.weixin.qq.com/s/4VbipLVR34D_iOMiJntHnw) 165 | 166 | - [STL容器源码分析](https://mp.weixin.qq.com/s/Khys6g82qRQxqJjKSUTreA) 167 | 168 | - [malloc内存分配器原理](https://mp.weixin.qq.com/s/KKsMAYh9mgr0GEgqxKWA_g) 169 | 170 | #### 性能优化 171 | 172 | - [高效代码的一些建议](https://mp.weixin.qq.com/s/B0cKUQyL4q34Zb6TggtcRQ) 173 | 174 | - [编译器都做了哪些优化](https://mp.weixin.qq.com/s/_Dunn97fMDkEhkPidf1IJw) 175 | 176 | - [strip必知必会](https://mp.weixin.qq.com/s/twFor039zSOuqVKE4XdX0Q) 177 | 178 | - [静态代码分析工具:让bug无所遁形](https://mp.weixin.qq.com/s?__biz=MzkyODE5NjU2Mw==&mid=2247493747&idx=1&sn=39db000227fb46570dfff160ca89b413&chksm=c21edacff56953d95f357a6a8b8eca12dd810d20dd170858867377795a21e86b5ae127fb871f#rd) 179 | 180 | - [科普内存对齐](https://mp.weixin.qq.com/s/iJlOcQjVf6e7a3K84fdekg) 181 | 182 | - [高性能代码必备:CPU Cache](https://mp.weixin.qq.com/s/iKWQZxn6XYKU9KnlBRynfg) 183 | 184 | - [if-else效率为什么这么低?](https://mp.weixin.qq.com/s/m8avve1ahFrf8KJ0n2w8mA) 185 | 186 | - [如何消灭if-else](https://mp.weixin.qq.com/s/cSrJao-sexcS18EhIQlA-Q) 187 | 188 | - [性能调优工具大全](https://mp.weixin.qq.com/s/WL-agdox7uNaPe4PV8HgQg) 189 | 190 | - [如何优化Linux程序体积大小](https://mp.weixin.qq.com/s/oOExVor6RMDE3SHG4UZ1_Q) 191 | 192 | - [代码效率分析](https://mp.weixin.qq.com/s/i7V6lmtQpuFADYZ8ApmkWA) 193 | 194 | - [并发方向的优化](https://mp.weixin.qq.com/s/sxlmaCChrosZ8Qcaew7G7A) 195 | 196 | - [内存方向的优化](https://mp.weixin.qq.com/s/0uK98WsXv57lJYakA2oqGg) 197 | 198 | - [如何设计结构体](https://mp.weixin.qq.com/s/FbaGdRgUFmfXYY52NxbbbA) 199 | 200 | - [如何设计C++的类](https://mp.weixin.qq.com/s/p7zzhYgJklbNhkl362r0fQ) 201 | 202 | - [多线程的一些建议](https://mp.weixin.qq.com/s/SkH2CotAenSE79I2LMbD0w) 203 | 204 | #### 造轮子必备 205 | 206 | - [如何设计高效的log模块](https://mp.weixin.qq.com/s/hdkjkNaLQFGP2M83GN7JkQ) 207 | 208 | - [如何实现功能完备的线程池](https://mp.weixin.qq.com/s/uz85-w9ZfwRP0ZZCI7jOzQ) 209 | 210 | - [如何实现定时器](https://mp.weixin.qq.com/s/Hmn5B7qctAp20tggnQcFTw) 211 | 212 | - [怎么自己写一个内存泄漏检测工具](https://mp.weixin.qq.com/s/NE4Ozd2XtIshN45YJjR04Q) 213 | 214 | - [简单的对象池实现](https://mp.weixin.qq.com/s/bWe8dLs-sgoCI_5sQbeOaw) 215 | 216 | - [简单的shared_ptr实现,代码有点bug,具体见评论区](https://mp.weixin.qq.com/s/n8O0Xn8hqpa5On-h8Zlcbg) 217 | 218 | #### 编译链接 219 | 220 | - [gcc test.cc的背后经历了什么?](https://mp.weixin.qq.com/s/PaXLQnaCjGkQGIjnPnqRww) 221 | 222 | - [程序一定要从main函数开始运行吗?](https://mp.weixin.qq.com/s/ZkLAykPN5UbZuYsDn97kDA) 223 | 224 | - [程序链接与分段知识点](https://mp.weixin.qq.com/s/p6WyMlTQJ6ZumZFdt3531w) 225 | 226 | - [可执行程序装载到虚拟内存全过程](https://mp.weixin.qq.com/s/86HecgrAj4gH7ZQi0jF0Ng) 227 | 228 | - [函数调用全流程](https://mp.weixin.qq.com/s/rHLPyrEPLHdZCuJ175Cung) 229 | 230 | - [共享库的版本控制](https://mp.weixin.qq.com/s/nQgM0zT24chXn7kzhQ5ypA) 231 | 232 | - [动态链接原理](https://mp.weixin.qq.com/s/IE7nE6ERb_0OtnZbF-GK8g) 233 | 234 | - [静态链接与动态链接的区别](https://mp.weixin.qq.com/s/VDnTE6ImQXt_MxbhEHQk_Q) 235 | 236 | - [科普文:编译链接的套路](https://mp.weixin.qq.com/s/R1hiec0Z0T5bPHswkLNQWw) 237 | 238 | - [Debug模式和Release模式的区别](https://mp.weixin.qq.com/s/A_XLPZ-FgYIUMHLYVum7jQ) 239 | 240 | 241 | #### 调试系列 242 | 243 | - [代码调试手段](https://mp.weixin.qq.com/s/wFy3EueN1oEMTKjeNBYuRg) 244 | 245 | - [Linux如何调试内存泄漏](https://mp.weixin.qq.com/s/0JsxzsOAQfLPCSpldYkKkA) 246 | 247 | - [内存泄漏调试方法论](https://mp.weixin.qq.com/s/K2Fvn6jDm71fdpQjix_wrg) 248 | 249 | - [gdb使用指南](https://mp.weixin.qq.com/s/S-B2KZ7UTaIDzAgKG32VAQ) 250 | 251 | - [如何使用gdb定位死锁问题](https://mp.weixin.qq.com/s/O4xuCcPMXG4Y9ktIn8578A) 252 | 253 | 254 | ### 操作系统 255 | 256 | - [推荐清华老师的操作系统视频](https://www.bilibili.com/video/BV1uW411f72n?from=search&seid=7182050251415608805) 257 | 258 | - [推荐哈工大老师的操作系统视频](https://www.bilibili.com/video/BV1d4411v7u7?from=search&seid=7182050251415608805) 259 | 260 | - [推荐一个内核学习的视频](https://www.bilibili.com/video/BV1yD4y1m7Q9) 261 | 262 | - [进程和线程相关知识点总结](https://mp.weixin.qq.com/s/NCl17jrOwP_A017nUqOkJQ) 263 | 264 | - [操作系统内存管理知识点](https://mp.weixin.qq.com/s/yzvye0rJto1P7zSTh03kZQ) 265 | 266 | - [64位系统与32位系统的区别](https://mp.weixin.qq.com/s/Ls0YAbXPHLdu7LG3VzNsTw) 267 | 268 | - [malloc内存分配器实现原理](https://mp.weixin.qq.com/s/KKsMAYh9mgr0GEgqxKWA_g) 269 | 270 | - [Linux 内核官方文档](https://docs.kernel.org/index.html) 271 | 272 | - [Linux 内核源码](https://github.com/torvalds/linux) 273 | 274 | - [Linux 内核揭秘](https://xinqiu.gitbooks.io/linux-insides-cn/content/index.html) 275 | 276 | - [Linux 内核模块编程指南](https://sysprog21.github.io/lkmpg/) 277 | 278 | - [Linux 内存布局与malloc底层实现分析](https://mp.weixin.qq.com/s/3bXAGR_7XLX21nkdl9dQ8Q) 279 | 280 | 281 | ### 设计模式 282 | 283 | - [推荐一个非常好的学习设计模式的网站](https://refactoringguru.cn/design-patterns) 284 | 285 | - [设计模式汇总](https://mp.weixin.qq.com/s/knzV1-bmrI7jhQqnhogGkw) 286 | 287 | - [双分派设计模式](https://mp.weixin.qq.com/s/I1qXomFD1TiGnUV48DXrxw) 288 | 289 | - [pimpl模式](https://mp.weixin.qq.com/s/LyPabf13uJ4QMwEF1rXf6A) 290 | 291 | 292 | ### Java 293 | 294 | - [JNI如何巧妙获取env](https://mp.weixin.qq.com/s/Q7hq4BceQ3JCr3CXhbma4g) 295 | 296 | - [JNI内存管理之Local Reference和Global Reference知识点](https://mp.weixin.qq.com/s/5Q2Exx9W5BckpI3AhzShHQ) 297 | 298 | - [Android Native内存泄漏调试心得](https://mp.weixin.qq.com/s/AlqD2Wp2g6qUMXG9zeqEow) 299 | 300 | - [JNI知识点](https://mp.weixin.qq.com/s/KFWYOq3QRXeyu2ygeuy5-Q) 301 | 302 | 303 | ### 算法 304 | 305 | - [袁厨的算法小屋](https://github.com/chefyuan/algorithm-base) 306 | 307 | - [厨子的网站](http://www.chengxuchu.com) 308 | 309 | - [一定要猛刷leetcode](https://leetcode-cn.com/) 310 | 311 | ## 知名大学计算机系开源课程收录 312 | 313 | - [浙江大学课程攻略共享计划](https://qsctech.github.io/zju-icicles/) 314 | 315 | - [清华大学计算机系课程攻略](https://rekcarc-tsc-uht.readthedocs.io/en/latest/) 316 | 317 | - [北京大学课程资料民间整理](https://lib-pku.github.io/) 318 | 319 | - [上海交通大学课程资料分享](https://github.com/c-hj/SJTU-Courses) 320 | 321 | - [北京邮电大学计算机考研信息汇总](https://ningzimu.github.io/See_you_in_BUPT/) 322 | 323 | - [北京航空航天大学(北航)课程作业资料共享计划](https://github.com/TheBloodthirster/BUAA_Course_Sharing) 324 | 325 | - [华北电力大学计算机系课程攻略](https://github.com/IammyselfYBX/NCEPU_CS_course) 326 | 327 | ## 深度学习 328 | - [《PapersWithCode》对机器学习做了分类,检索对应的模型非常方便,这个网站包含:论文 + github实现代码 + 经典 + 最新 + 多版本对比 + 神器](https://paperswithcode.com/) 329 | - [《动手学强化学习》 - 上海交通大学 - 课程主页](http://hrl.boyuai.com/) 330 | - [《动手学深度学习》 - 李沐 亚马逊资深首席科学家 - 课程主页](https://courses.d2l.ai/zh-v2/) 331 | - [ 动手学深度学习课程的 markdown 笔记和相关的 jupyter 代码](https://github.com/HIT-UG-Group/DeepLearning-MuLi-Notes) 332 | 333 | ## 科普 334 | 335 | - [计算机为什么从0开始计数](https://mp.weixin.qq.com/s/6zAmABxH8jHy8l5r0_9Kag) 336 | 337 | - [为什么不能include cpp](https://mp.weixin.qq.com/s/NVEZnF1HqpIMSBlw_PXwyA) 338 | 339 | - [if-else和switch-case效率对比分析](https://mp.weixin.qq.com/s/mTik1pfNigGnVnB6oK8ilA) 340 | 341 | ## 生活 342 | 343 | - [打工人保命指南](https://mp.weixin.qq.com/s/4hY8xM7omrVOnvexJmCehA) 344 | 345 | - [不要为35岁焦虑](http://mp.weixin.qq.com/s?__biz=MzkyODE5NjU2Mw==&mid=2247486284&idx=1&sn=0b6109414afaf5164c5a782407bbe923&chksm=c21d39f0f56ab0e6ca8115cceb9b3774fcdbec3aab221635e2fb281be1b381d259280d30c44b&token=830665182&lang=zh_CN#rd) 346 | 347 | - [防诈骗指南](http://mp.weixin.qq.com/s?__biz=MzkyODE5NjU2Mw==&mid=2247486676&idx=1&sn=709abc972c52ea6019f93f562da2efee&chksm=c21d3e68f56ab77eec8e6215321413f1f707f4cae8f72bdc135d58f22b88e4ce17f64f93f8e0&token=1242239139&lang=zh_CN#rd) 348 | 349 | ## 其它 350 | 351 | - [C语言如何实现动态扩容的string](https://mp.weixin.qq.com/s/6T4LN3Qkc9OJeCQEBiivcQ) 352 | 353 | - [音视频学习资料整理](https://mp.weixin.qq.com/s/QE-Zqd9oBQZI4T73ehITKg) 354 | 355 | - [C++全链路追踪方案](https://mp.weixin.qq.com/s/ZZd_o_x5Ti8o8haMjG0btw) 356 | 357 | - [开源库推荐](https://mp.weixin.qq.com/s/LSy4fnWKMEln7v9QO-aeZA) 358 | 359 | ## 机器人 360 | 361 | - [开源机器人学习指南](https://github.com/qqfly/how-to-learn-robotics) 362 | -------------------------------------------------------------------------------- /doc/C++20新特性.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chengxumiaodaren/cpp-learning/cd1626f629b18d27a19d480ba9ef42c38a15d0cc/doc/C++20新特性.png -------------------------------------------------------------------------------- /doc/C++入门知识点.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chengxumiaodaren/cpp-learning/cd1626f629b18d27a19d480ba9ef42c38a15d0cc/doc/C++入门知识点.png -------------------------------------------------------------------------------- /doc/C++必备知识点.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chengxumiaodaren/cpp-learning/cd1626f629b18d27a19d480ba9ef42c38a15d0cc/doc/C++必备知识点.png -------------------------------------------------------------------------------- /doc/C++的坑.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chengxumiaodaren/cpp-learning/cd1626f629b18d27a19d480ba9ef42c38a15d0cc/doc/C++的坑.png -------------------------------------------------------------------------------- /doc/MoreCppIdioms.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chengxumiaodaren/cpp-learning/cd1626f629b18d27a19d480ba9ef42c38a15d0cc/doc/MoreCppIdioms.pdf -------------------------------------------------------------------------------- /doc/c++学习路线图.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chengxumiaodaren/cpp-learning/cd1626f629b18d27a19d480ba9ef42c38a15d0cc/doc/c++学习路线图.png -------------------------------------------------------------------------------- /doc/profiling_tools.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chengxumiaodaren/cpp-learning/cd1626f629b18d27a19d480ba9ef42c38a15d0cc/doc/profiling_tools.pdf -------------------------------------------------------------------------------- /doc/程序喵大人学习宝典第一版.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chengxumiaodaren/cpp-learning/cd1626f629b18d27a19d480ba9ef42c38a15d0cc/doc/程序喵大人学习宝典第一版.pdf -------------------------------------------------------------------------------- /img/cxmdr.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chengxumiaodaren/cpp-learning/cd1626f629b18d27a19d480ba9ef42c38a15d0cc/img/cxmdr.jpg -------------------------------------------------------------------------------- /img/wechat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chengxumiaodaren/cpp-learning/cd1626f629b18d27a19d480ba9ef42c38a15d0cc/img/wechat.jpg -------------------------------------------------------------------------------- /src/test_multi_array.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void test_two_dim_array() { 5 | int multi_array_native[3][4]; 6 | std::array, 4> multi_array; 7 | ///< 但其实它俩不相同,应该是 8 | std::array, 3> multi_arrays; 9 | } 10 | 11 | template 12 | using TwoDimMatrix = std::array, R>; 13 | 14 | void test_two_dim_matrix() { 15 | constexpr size_t row = 2; 16 | constexpr size_t col = 3; 17 | TwoDimMatrix mat; 18 | int k = 0; 19 | for (int i = 0; i < row; ++i) { 20 | for (int j = 0; j < col; ++j) { 21 | mat[i][j] = ++k; 22 | } 23 | } 24 | 25 | for (int i = 0; i < row; ++i) { 26 | for (int j = 0; j < col; ++j) { 27 | std::cout << mat[i][j] << " "; 28 | } 29 | } 30 | } 31 | 32 | ///< 利用模板元编程 33 | template 34 | struct Matrix { 35 | using Col = typename Matrix::type; 36 | using type = std::array; 37 | }; 38 | 39 | template 40 | struct Matrix { 41 | using type = std::array; 42 | }; 43 | 44 | void test_multi_array() { 45 | constexpr size_t a = 2; 46 | constexpr size_t b = 3; 47 | constexpr size_t c = 4; 48 | constexpr size_t d = 5; 49 | Matrix::type mat; 50 | int u = 0; 51 | for (int i = 0; i < a; ++i) { 52 | for (int j = 0; j < b; ++j) { 53 | for (int k = 0; k < c; ++k) { 54 | for (int m = 0; m < d; ++m) { 55 | mat[i][j][k][m] = ++u; 56 | } 57 | } 58 | } 59 | } 60 | for (int i = 0; i < a; ++i) { 61 | for (int j = 0; j < b; ++j) { 62 | for (int k = 0; k < c; ++k) { 63 | for (int m = 0; m < d; ++m) { 64 | std::cout << mat[i][j][k][m] << " "; 65 | } 66 | } 67 | } 68 | } 69 | } 70 | 71 | int main() { 72 | test_two_dim_matrix(); 73 | std::cout << "\n"; 74 | test_multi_array(); 75 | } 76 | -------------------------------------------------------------------------------- /src/test_shared_ptr.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class SharedCount { 5 | public: 6 | SharedCount() : count_{1} {} 7 | 8 | void add() { ++count_; } 9 | 10 | void minus() { --count_; } 11 | 12 | int get() const { return count_; } 13 | 14 | private: 15 | std::atomic count_; 16 | }; 17 | 18 | template 19 | class SharedPtr { 20 | public: 21 | template 22 | friend class SharedPtr; 23 | 24 | template 25 | friend SharedPtr static_pointer_cast(const SharedPtr& p); 26 | 27 | SharedPtr(T* ptr) : ptr_{ptr}, ref_count_{new SharedCount} {} 28 | 29 | SharedPtr() : ptr_{nullptr}, ref_count_{new SharedCount} {} 30 | 31 | ~SharedPtr() { clean(); } 32 | 33 | SharedPtr(const SharedPtr& p) { 34 | this->ptr_ = p.ptr_; 35 | this->ref_count_ = p.ref_count_; 36 | ref_count_->add(); 37 | } 38 | 39 | SharedPtr(SharedPtr&& p) { 40 | this->ptr_ = p.ptr_; 41 | this->ref_count_ = p.ref_count_; 42 | p.ptr_ = nullptr; 43 | p.ref_count_ = nullptr; 44 | } 45 | 46 | SharedPtr& operator=(const SharedPtr& p) { 47 | if (this == &p) return *this; 48 | clean(); 49 | this->ptr_ = p.ptr_; 50 | this->ref_count_ = p.ref_count_; 51 | ref_count_->add(); 52 | return *this; 53 | } 54 | 55 | SharedPtr& operator=(SharedPtr&& p) { 56 | if (this == &p) return *this; 57 | clean(); 58 | this->ptr_ = p.ptr_; 59 | this->ref_count_ = p.ref_count_; 60 | p.ptr_ = nullptr; 61 | p.ref_count_ = nullptr; 62 | return *this; 63 | } 64 | 65 | int use_count() { return ref_count_->get(); } 66 | 67 | T* get() const { return ptr_; } 68 | 69 | T* operator->() const { return ptr_; } 70 | 71 | T& operator*() const { return *ptr_; } 72 | 73 | operator bool() const { return ptr_; } 74 | 75 | private: 76 | template 77 | SharedPtr(const SharedPtr& p, T* ptr) { 78 | this->ptr_ = ptr; 79 | this->ref_count_ = p.ref_count_; 80 | ref_count_->add(); 81 | } 82 | 83 | void clean() { 84 | if (ref_count_) { 85 | ref_count_->minus(); 86 | if (ref_count_->get() == 0) { 87 | if (ptr_) delete ptr_; 88 | delete ref_count_; 89 | } 90 | } 91 | } 92 | 93 | T* ptr_; 94 | SharedCount* ref_count_; 95 | }; 96 | 97 | template 98 | SharedPtr static_pointer_cast(const SharedPtr& p) { 99 | T* ptr = static_cast(p.get()); 100 | return SharedPtr(p, ptr); 101 | } 102 | 103 | struct A { 104 | A() { std::cout << "A() \n"; } 105 | ~A() { std::cout << "~A() \n"; } 106 | }; 107 | 108 | struct B : A { 109 | B() { std::cout << "B() \n"; } 110 | ~B() { std::cout << "~B() \n"; } 111 | }; 112 | 113 | void test_cast_shared() { 114 | B* a = new B; 115 | SharedPtr ptr(a); 116 | { 117 | std::cout << ptr.use_count() << std::endl; 118 | SharedPtr b = static_pointer_cast(ptr); 119 | std::cout << ptr.use_count() << std::endl; 120 | SharedPtr c = ptr; 121 | std::cout << ptr.use_count() << std::endl; 122 | SharedPtr d = ptr; 123 | std::cout << ptr.use_count() << std::endl; 124 | } 125 | std::cout << ptr.use_count() << std::endl; 126 | } 127 | 128 | void test_simple_shared() { 129 | A* a = new A; 130 | SharedPtr ptr(a); 131 | { 132 | std::cout << ptr.use_count() << std::endl; 133 | SharedPtr b = ptr; 134 | std::cout << ptr.use_count() << std::endl; 135 | SharedPtr c = ptr; 136 | std::cout << ptr.use_count() << std::endl; 137 | SharedPtr d = std::move(b); 138 | std::cout << ptr.use_count() << std::endl; 139 | } 140 | std::cout << ptr.use_count() << std::endl; 141 | } 142 | 143 | int main() { test_simple_shared(); } 144 | -------------------------------------------------------------------------------- /src/test_unique_ptr.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | template 4 | class UniquePtr { 5 | public: 6 | UniquePtr(T* ptr) : ptr_{ptr} {} 7 | 8 | UniquePtr() : ptr_{nullptr} {} 9 | 10 | UniquePtr(const UniquePtr& p) = delete; 11 | UniquePtr& operator=(const UniquePtr& p) = delete; 12 | 13 | UniquePtr(UniquePtr&& p) { 14 | this->ptr_ = p.ptr_; 15 | p.ptr_ = nullptr; 16 | } 17 | 18 | UniquePtr& operator=(UniquePtr&& p) { 19 | clean(); 20 | this->ptr_ = p.ptr_; 21 | p.ptr_ = nullptr; 22 | return *this; 23 | } 24 | 25 | T* get() const { return ptr_; } 26 | 27 | T* operator->() const { return ptr_; } 28 | 29 | T& operator*() const { return *ptr_; } 30 | 31 | operator bool() const { return ptr_; } 32 | 33 | ~UniquePtr() { clean(); } 34 | 35 | private: 36 | void clean() { 37 | if (ptr_) delete ptr_; 38 | } 39 | 40 | T* ptr_; 41 | }; 42 | 43 | struct A { 44 | A() { std::cout << "A() \n"; } 45 | ~A() { std::cout << "~A() \n"; } 46 | }; 47 | 48 | int main() { 49 | A* a = new A; 50 | UniquePtr ptr(a); 51 | UniquePtr b(std::move(ptr)); 52 | } 53 | -------------------------------------------------------------------------------- /src/variant/test_variant_index.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void test_index() { 6 | std::variant var; 7 | var = 1; 8 | std::cout << var.index() << "\n"; 9 | var = 2.90f; 10 | std::cout << var.index() << "\n"; 11 | var = std::string("hello world"); 12 | std::cout << var.index() << "\n"; 13 | } 14 | 15 | template 16 | struct get_index; 17 | 18 | template 19 | struct get_index_impl {}; 20 | 21 | template 22 | struct get_index_impl : std::integral_constant {}; 23 | 24 | template 25 | struct get_index_impl : get_index_impl {}; 26 | 27 | template 28 | struct get_index> : get_index_impl<0, T, Ts...> {}; 29 | 30 | template 31 | constexpr auto get_index_v = get_index::value; 32 | 33 | using variant_t = std::variant; 34 | 35 | constexpr static auto kPlaceholderIndex = get_index_v; 36 | constexpr static auto kIntIndex = get_index_v; 37 | constexpr static auto kFloatIndex = get_index_v; 38 | constexpr static auto kStringIndex = get_index_v; 39 | 40 | void test_using_index() { 41 | std::cout << "kPlaceholderIndex " << kPlaceholderIndex << "\n"; 42 | std::cout << "kIntIndex " << kIntIndex << "\n"; 43 | std::cout << "kFloatIndex " << kFloatIndex << "\n"; 44 | std::cout << "kStringIndex " << kStringIndex << "\n"; 45 | 46 | auto custom_visitor = [](const auto& value) { 47 | switch (value.index()) { 48 | case kPlaceholderIndex: 49 | std::cout << "placehodler value " 50 | << "\n"; 51 | break; 52 | case kIntIndex: 53 | std::cout << "int value " << std::get(value) << "\n"; 54 | break; 55 | case kFloatIndex: 56 | std::cout << "float value " << std::get(value) << "\n"; 57 | break; 58 | case kStringIndex: 59 | std::cout << "string value " << std::get(value) << "\n"; 60 | break; 61 | } 62 | }; 63 | variant_t var; 64 | custom_visitor(var); 65 | 66 | var = 1; 67 | custom_visitor(var); 68 | 69 | var = 2.90f; 70 | custom_visitor(var); 71 | 72 | var = std::string("hello world"); 73 | custom_visitor(var); 74 | 75 | var = std::string("hello type"); 76 | } 77 | 78 | int main() { test_using_index(); } 79 | -------------------------------------------------------------------------------- /src/variant/test_variant_monostate.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /** 5 | * @brief 为什么要使用monostate 6 | * 7 | */ 8 | 9 | struct S { 10 | S(int i) : value{i} {} 11 | int value; 12 | }; 13 | 14 | void test_monostate() { 15 | std::variant var; 16 | var = 12; 17 | std::cout << std::get(var).value << "\n"; 18 | } 19 | 20 | /* 21 | void test_monostate2() { 22 | ///< 编译失败,S如果没有构造函数,需要加monostate 23 | std::variant var; 24 | var = 12; 25 | std::cout << std::get(var).value << "\n"; 26 | } 27 | */ 28 | 29 | void test_variant() { 30 | std::variant var; 31 | var = 12; 32 | std::cout << std::get(var) << "\n"; 33 | var = 12.1f; 34 | std::cout << std::get(var) << "\n"; 35 | } 36 | 37 | int main() { 38 | test_monostate(); 39 | test_variant(); 40 | } 41 | -------------------------------------------------------------------------------- /src/variant/test_variant_polymorphism.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct A { 6 | void func() const { std::cout << "func A \n"; } 7 | }; 8 | 9 | struct B { 10 | void func() const { std::cout << "func B \n"; } 11 | }; 12 | 13 | struct CallFunc { 14 | void operator()(const A& a) { a.func(); } 15 | void operator()(const B& b) { b.func(); } 16 | }; 17 | 18 | void test_no_param_polymorphism() { 19 | std::variant var; 20 | var = A(); 21 | std::visit(CallFunc{}, var); 22 | var = B(); 23 | std::visit(CallFunc{}, var); 24 | } 25 | 26 | struct C { 27 | void func(int value) const { std::cout << "func C " << value << "\n"; } 28 | }; 29 | 30 | struct D { 31 | void func(int value) const { std::cout << "func D " << value << "\n"; } 32 | }; 33 | 34 | struct CallFuncParam { 35 | void operator()(const C& c) { c.func(value); } 36 | void operator()(const D& d) { d.func(value); } 37 | 38 | int value; 39 | }; 40 | 41 | void test_param_polymorphism() { 42 | std::variant var; 43 | var = C(); 44 | std::visit(CallFuncParam{1}, var); 45 | var = D(); 46 | std::visit(CallFuncParam{2}, var); 47 | } 48 | 49 | void test_param_lambda_polymorphism() { 50 | std::variant var; 51 | int value = 1; 52 | auto caller = [&value](const auto& v) { v.func(value); }; 53 | std::visit(caller, var); 54 | value = 2; 55 | std::visit(caller, var); 56 | } 57 | 58 | int main() { 59 | test_no_param_polymorphism(); 60 | std::cout << " ====== \n"; 61 | test_param_polymorphism(); 62 | std::cout << " ====== \n"; 63 | test_param_lambda_polymorphism(); 64 | } 65 | -------------------------------------------------------------------------------- /src/variant/test_variant_visit.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct Visitor { 6 | void operator()(int i) const { std::cout << "int " << i << "\n"; } 7 | 8 | void operator()(float f) const { std::cout << "float " << f << "\n"; } 9 | 10 | void operator()(std::string s) const { std::cout << "string " << s << "\n"; } 11 | }; 12 | 13 | void test_visitor_functor() { 14 | std::variant var; 15 | var = 1; 16 | std::visit(Visitor(), var); 17 | var = 2.90f; 18 | std::visit(Visitor(), var); 19 | var = std::string("hello world"); 20 | std::visit(Visitor(), var); 21 | } 22 | 23 | void test_visitor_lambda() { 24 | std::variant var; 25 | var = 1; 26 | std::visit([](const auto& value) { std::cout << "value " << value << "\n"; }, var); 27 | var = 2.90f; 28 | std::visit([](const auto& value) { std::cout << "value " << value << "\n"; }, var); 29 | var = std::string("hello world"); 30 | std::visit([](const auto& value) { std::cout << "value " << value << "\n"; }, var); 31 | var = std::string("hello type"); 32 | std::visit( 33 | [](const auto& value) { 34 | using T = std::decay_t; 35 | if constexpr (std::is_same_v) { 36 | std::cout << "int value " << value << "\n"; 37 | } else if constexpr (std::is_same_v) { 38 | std::cout << "float value " << value << "\n"; 39 | } else if constexpr (std::is_same_v) { 40 | std::cout << "string value " << value << "\n"; 41 | } 42 | }, 43 | var); 44 | } 45 | 46 | int main() { 47 | test_visitor_functor(); 48 | std::cout << "=========== \n"; 49 | test_visitor_lambda(); 50 | } 51 | -------------------------------------------------------------------------------- /src/variant/test_why_variant.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | union MyUnion { 6 | int a; 7 | float b; 8 | double c; 9 | }; 10 | 11 | void test_simple_union() { 12 | MyUnion u; 13 | u.a = 1; 14 | std::cout << u.a << "\n"; 15 | 16 | u.b = 1.32f; 17 | std::cout << u.b << "\n"; 18 | 19 | u.c = 2.32; 20 | std::cout << u.c << "\n"; 21 | } 22 | 23 | struct A { 24 | A() = default; 25 | A(int aa) : a{aa} { std::cout << "A() \n"; } 26 | ~A() { std::cout << "~A() \n"; } 27 | int a; 28 | }; 29 | 30 | struct B { 31 | B() = default; 32 | B(float bb) : b{bb} { std::cout << "B() \n"; } 33 | ~B() { std::cout << "~B() \n"; } 34 | float b; 35 | }; 36 | 37 | union MyStructUnion { 38 | A a; 39 | B b; 40 | /** 41 | * @brief 在析构函数中我要做什么?不知道当前类型究竟是A还是B 42 | * 那调用 a.~A() 还是 b.~B() ? 43 | */ 44 | ~MyStructUnion() { std::cout << "~MyStructUnion() \n"; } 45 | }; 46 | 47 | /** 48 | * @brief 需要手动调用析构函数 49 | * 50 | */ 51 | void test_struct_union() { 52 | MyStructUnion u; 53 | 54 | new (&u.a) A(1); 55 | std::cout << u.a.a << "\n"; 56 | u.a.~A(); 57 | 58 | u.b = B(2.3f); 59 | std::cout << u.b.b << "\n"; 60 | u.b.~B(); 61 | } 62 | 63 | struct C { 64 | C() = default; 65 | C(std::string cc) : c{cc} { std::cout << "C() \n"; } 66 | ~C() { std::cout << "~C() \n"; } 67 | std::string c; 68 | }; 69 | 70 | /** 71 | * @brief 使用variant完全不需要手动调用构造和析构函数,它会自动处理好所有逻辑,非常方便 72 | * 73 | */ 74 | void test_variant() { 75 | std::variant u; 76 | u = 1; 77 | std::cout << std::get(u).a << "\n"; 78 | u = std::string("dsd"); 79 | std::cout << std::get(u).c << "\n"; 80 | } 81 | 82 | int main() { test_variant(); } 83 | --------------------------------------------------------------------------------