V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Symbo1ic
V2EX  ›  C++

求助,想获得一些关于 C++学习的建议

  •  
  •   Symbo1ic · 2023-03-29 09:58:01 +08:00 · 4211 次点击
    这是一个创建于 365 天前的主题,其中的信息可能已经有所发展或是发生改变。

    本人为大三本科生,因为对游戏引擎感兴趣自己正在学习并且尝试实践 c++。这是我的项目链接LRE2。最近看了很多文章,觉得自己对 cpp 理解很有问题,比如说关于share_ptr的滥用问题,在个人的项目中处理的非常差。还有就是关于语言的高级特性也是完全不明白,因此希望得到一些关于 cpp 学习的路径。很多推荐的材料感觉都偏基础,而且大部分都是视频材料,个人吸收效果不是很好。如果可以的话希望得到一些文字材料推荐。

    25 条回复    2023-03-30 11:31:38 +08:00
    111qqz
        1
    111qqz  
       2023-03-29 10:04:18 +08:00
    Symbo1ic
        2
    Symbo1ic  
    OP
       2023-03-29 10:07:17 +08:00
    @111qqz 这个感觉还是太底层了,个人认为我需要的是教程,不是工具书。
    LaTero
        3
    LaTero  
       2023-03-29 10:26:04 +08:00 via Android
    core guidelines 看一下?都很实用的。https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines
    inhzus
        4
    inhzus  
       2023-03-29 10:39:54 +08:00
    有看过经典三件套吗 Effective C++, More Effective C++, Effective Modern C++
    高级特性比如 C++ 20/23 ,cppcon 有一些大纲性质的视频分类的挺好,大概了解之后,自己用一用就会了。
    其余的参考 cppreference 比如 C++17 core language features ,逐个查漏补缺...
    sl0000
        5
    sl0000  
       2023-03-29 10:46:14 +08:00   ❤️ 1
    高速上手 C++ 11/14/17/20 https://changkun.de/modern-cpp/
    zeal7s
        6
    zeal7s  
       2023-03-29 10:50:16 +08:00
    shared_ptr 主要是跟所有权相关,一般一个类用拥有一个对象才会使用 shared_ptr ,如果只是 access 一个对象,用 weak_ptr 或者 raw pointer 就可以。

    举个例子,父窗口在逻辑上拥有子窗口,那么父窗口类中就用 shared_ptr hold 住子窗口对象。当子窗口需要使用的父窗口的一些函数时,子窗口就通过 weak_ptr 来 access 父窗口对象进而调用父窗口的函数。这样可以避免循环引用。

    一般 shared_ptr 和 weak_ptr 配对使用,unique_ptr 和 raw pointer 配对使用,你分别用这两种方法来实现一个双向链表的功能比如插入和删除就能有所体会。

    平时写代码能用 unique_ptr/raw_pointer 配对就尽量用,避免 shared_ptr 引用计数的开销。但是有些情况 shared_ptr 仍然不得不用:比如实现 Graph 相关的算法时候,一个节点会被两个以上节点指向,而且也没有明确的所有权概念。

    另外,仅在需要操作对象生命周期时使用智能指针作为函数参数,这部分可以看 C++ Core Guidlines ,讲得比较细。

    我自己也是感觉很多 C++书籍讲解智能指针的使用时挺模糊的,比如 C++ primer ,看完语法是会了,但是一写代码就感觉不对劲,每次都会自我怀疑这样写到底对不对。

    平时学 C++我比较常看 CppCon 演讲,可以学到很多。
    B 站推荐两个 Up 主,感觉 C++相关的系列视频讲得挺好的:
    https://space.bilibili.com/1292761396
    https://space.bilibili.com/263032155
    yangzhezjgs
        7
    yangzhezjgs  
       2023-03-29 10:51:59 +08:00
    我大概理解你的意思,你应该想更多“why”这个层面为什么 C++这么设计和具体场景下该怎么写 C++的建议,推荐几本我最近在看的书:
    1.《现代 C++语言核心特性解析》 https://book.douban.com/subject/35602582/
    2.《深入应用 C++11 》 https://book.douban.com/subject/26419368/
    3.《 C++ Software Design 》 https://book.douban.com/subject/35913533/
    zeal7s
        8
    zeal7s  
       2023-03-29 10:59:02 +08:00
    我记得 CppCon 里有好几个演讲专门讲智能指针的使用,很细,也有不少坑,你可以去搜搜
    yangzhezjgs
        9
    yangzhezjgs  
       2023-03-29 10:59:34 +08:00
    4.《 C++沉思录》也不错,也是研究设计和编程思想,只是成书年代比较早了,也推荐一下
    我觉得核心是要通过学习,在脑子里形成一套写代码时的决策树,了解各种写法背后的权衡和优劣,做出相对正确的选择
    chatWell1
        10
    chatWell1  
       2023-03-29 11:12:19 +08:00
    1. 《 C++语言的设计与演化》
    2. 《深度探究 C++对象模型》
    3. 《 STL 深入浅出》
    4. 《 C++沉思录》
    Yeen
        11
    Yeen  
       2023-03-29 11:15:06 +08:00
    C++ PRIMER
    Inside the c++ object model
    深入理解计算机系统

    剩下的就是自己实践几个超过 2 万行代码的工程,阅读优秀的开源项目。

    good luck
    hankai17
        12
    hankai17  
       2023-03-29 11:49:39 +08:00
    9L + 1
    书本是对知识的总结
    zuosiruan
        13
    zuosiruan  
       2023-03-29 14:14:11 +08:00
    游戏引擎感兴趣......进不了米哈游这种级别的厂毫无意义。加油吧 小伙子
    ivvei
        14
    ivvei  
       2023-03-29 14:25:03 +08:00
    shared_ptr 我倾向于直接不用…… 资源谁分配就谁掌控,实在不要了就转走。
    fengjianxinghun
        15
    fengjianxinghun  
       2023-03-29 14:27:36 +08:00   ❤️ 2
    Symbo1ic
        16
    Symbo1ic  
    OP
       2023-03-29 16:43:44 +08:00
    @zeal7s 所有权这块真的很有启发性。在应对你提到的关于 unique 和 raw 搭配的情况,因为感觉 raw 并不是很靠谱,所以总是用 share 暴力解决。所有权这块的设计真的是很难,这块我也是一直没有弄的很明白。这块在这个视频中也会提到吗?另外感谢大家的分享!
    Symbo1ic
        17
    Symbo1ic  
    OP
       2023-03-29 16:45:17 +08:00
    @fengjianxinghun 正巧我有朋友学习过 rust ,说实话我感觉 rust 关于所有权那套解法还有一些思想也许可以套到 cpp 的开发中
    Symbo1ic
        18
    Symbo1ic  
    OP
       2023-03-29 16:48:29 +08:00
    @zuosiruan 是的,现在就业环境也不是很理想。总之先学!总会用到的
    Symbo1ic
        19
    Symbo1ic  
    OP
       2023-03-29 16:50:08 +08:00
    @yangzhezjgs 关于决策这块的说法不能再赞同了!这种东西也许就叫做 cpp 编程技能了吧。能够正确的在不同场景找到最优的解法,这真的很吸引人
    xmmmmovo
        20
    xmmmmovo  
       2023-03-29 18:38:13 +08:00
    游戏引擎......加油......先问一下你之前引擎用的多吗.....
    hanguofu
        21
    hanguofu  
       364 天前
    @zeal7s : 请问在什么场景下应该使用 unique_ptr/raw_pointer 啊 ?
    Symbo1ic
        22
    Symbo1ic  
    OP
       364 天前
    @xmmmmovo 目前的话有过 unity 游戏开发经验,之前有用 ue 的蓝图试着搭一些小东西。有的时候真的觉得他们在脚本层接口设计十分巧妙
    exch4nge
        23
    exch4nge  
       364 天前 via iPhone   ❤️ 1
    @Symbo1ic
    raw 用在能确定指针有效的情况,指针指向对象的生命周期肯定比当前类对象要长,能不用就不用。

    其余不用共享的用 unique ,明确表示有所有权。需要所有权转移也用,函数参数返回值等。
    (不用转移所有权,但用来延后初始化的场景建议用 optional )

    share_ptr 共享用,随处都用的话得避免循环应用,可以用 weak 解决。有时也用 atomic store load 来做原子操作多线程安全切换里面的对象

    内存使用大小上,share 最大,有 custom delete 的 unique 稍微大,没有的 unique 跟 raw 一样
    性能上 share 最差,unique 与 raw 接近
    zeal7s
        24
    zeal7s  
       364 天前   ❤️ 1
    @Symbo1ic 还是拿父窗口和子窗口来举例子,父窗口生成子窗口并且用 unique_ptr hold 住子窗口,子窗口生成时拿到指向父窗口的 raw pointer 。只要能保证父窗口的生命周期长于子窗口,即父窗口先于子窗口创建,晚于子窗口销毁,就能保证 raw pointer 不失效。

    所有权这块的使用原则就是一个对象逻辑上属于谁,所有权就是谁。现代 C++里面有所有权这个概念而其他语言里这个概念比较模糊的原因是,现代 C++通过 RAII 来控制堆上对象的生命周期。一个类拥有一个对象的所有权就表示这个类在调用自己的析构函数时也负责自动调用这个对象的析构函数。所以写程序时,想清楚堆上的对象由谁来负责销毁在逻辑上最合适,那么所有权也就想清楚了。

    换一种情况,如果程序中允许父窗口先于子窗口关闭,那么继续让父窗口通过 unique_ptr 持有子窗口就不合适了,因为父窗口销毁时也会自动调用子窗口的析构函数。此时需要一个窗口管理器来拥有所有的窗口,比如在窗口管理器中可以写:std::vector<std::unique_ptr<Window>> allWindows 。这样只要保证窗口管理器类晚于所有窗口销毁就行了。

    可以看看 muduo 这个 C++网络库,作者也有出书介绍,网上也有大量的文章和视频介绍。里面有挺多 unique_ptr 和 shared_ptr 用法。
    zeal7s
        25
    zeal7s  
       364 天前   ❤️ 1
    @Symbo1ic 比如你的代码里 https://github.com/hundan2015/LunaticRenderer2/blob/master/lunatic_engine/core/LunaticEngine.h#L14

    rendering_core_、entity_manager_和 resource_core_在逻辑上由引擎类负责管理销毁最合适,那么它们使用 unique_ptr 就行了。这里不存在共享所有权的情况,用 shared_ptr 就没必要了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3338 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 13:23 · PVG 21:23 · LAX 06:23 · JFK 09:23
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.