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

熟練了 C,被 C++把世界觀搞崩壞了

  •  1
     
  •   bitdepth · 2020-09-30 00:19:09 +08:00 via iPad · 9024 次点击
    这是一个创建于 1297 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我不敢說我很理解 C 當中的語法,水準也就給 linux kernel 寫寫 patch,會修補一下 gtk+程式。

    因為最近工作的關係,要開始用 C++ 剛開始的時候特別不理解 template 的用法,後來發現只是一個限制很多的 macro,當然很複雜的用處還是不懂。

    smart pointer 的 concepts 花了很多時間才明白。

    1. 第一是 c++對 type 的要求非常嚴格,類似在 C 中 void *這樣的儲存是絕對不允許的。
    2. 也是搞不懂上面講的 template,一直不懂怎麼在 wrapper class 當中放下那麼多型別的資料,後來才發現需要依賴類似 std::variant 這樣的方法。
    3. ownership 的控制,什麼時候可以用一下 raw pointer 不是什麼地方都要堅持只能用新的 smart pointer
    4. 對 class destructor 的要求,我之前不知道 C++ compiler 會幫忙填充 vtable 和進行 offset 換算的工作,這在 glib 中原本都是要手寫。

    上面這些明白以後,發現還是可能要在在 wrapper class 的 declare 前把那些存進來的 class 的 declare 全部導入進來,不隱私而去拖慢編譯速度。繼續問人之後發現,只需要在 wrapper class 做 customize operator= 和 desructor 即可。又發現一件事不明白

    1. 對 compiler 的行為不理解,特別是 object 的處理行為

    等別人手把手寫給我用例後,我不是很理解反正就先開始用了。 我今天在問如何生成 instance 並加入 smart pointer 列管的時候,得知了 RVO 這樣的東西,而不是保留在 C 當中的習慣使用 pointer

    在 c++很多時候應該使用 by value or by refer 。這讓我完全混亂了,不知道究竟 pointer 還有什麼意義。本來 C 當中有 pointer 完全是因為 performance issue 。而 c++ compiler 竟然會知道幫你改成 pointer copy 。

    第 1 条附言  ·  2020-09-30 02:05:00 +08:00
    copy constructor 忘記寫了,在第五條的描述場景下也是要 declare 的
    48 条回复    2020-10-27 01:15:20 +08:00
    asuraa
        1
    asuraa  
       2020-09-30 00:28:16 +08:00   ❤️ 2
    我也是 经常写 windows 内核 基本上用的也就是 c with class
    回过头写 c++项目 stl 不会用了 ....
    across
        2
    across  
       2020-09-30 01:07:07 +08:00 via Android
    还行,这还行,然后某一天,你需要写 JavaScript...... 😏
    Mohanson
        3
    Mohanson  
       2020-09-30 01:10:05 +08:00 via Android
    喜欢 c,写 c 的时候脑子里能实时想象出对应的机器码和内存布局,cpp 不行
    AJQA
        4
    AJQA  
       2020-09-30 01:11:56 +08:00 via Android
    @luodaoyi c with class 是什么?
    asuraa
        5
    asuraa  
       2020-09-30 01:24:05 +08:00
    @virtuemartx 大概就是 c++ 98
    woncode
        6
    woncode  
       2020-09-30 01:56:15 +08:00 via Android   ❤️ 1
    所以 c++是不是高级语言中最复杂最混乱的?
    fwee
        7
    fwee  
       2020-09-30 02:00:14 +08:00 via Android
    一直认为 C 是最好的语言,抽象层次正好够用。用更高级的语言就会有失去掌控感的感觉。
    wangyzj
        8
    wangyzj  
       2020-09-30 02:06:43 +08:00   ❤️ 1
    入前端坑吗?
    feast
        9
    feast  
       2020-09-30 02:16:19 +08:00 via Android
    C 艹不折磨人岂不是浪得虚名? Object 型语言都这样,你需要转换一下你的思路
    calmzhu
        10
    calmzhu  
       2020-09-30 03:08:46 +08:00   ❤️ 1
    多崩崩就习惯了
    aijam
        11
    aijam  
       2020-09-30 04:07:50 +08:00
    建议看看 the c++ programming language 第 2/3/4 章,感觉 lz 提的问题基本都 cover 了。
    ryd994
        12
    ryd994  
       2020-09-30 04:45:21 +08:00 via Android
    @virtuemartx 就是把 C++当 C 用。基本上是 C,少部分借用一下 C++的标准类,比如 list/map 。基本不定义新类,不利用 construct 之类的 C++类特性。
    billyzs
        13
    billyzs  
       2020-09-30 04:59:38 +08:00
    > 第一是 c++對 type 的要求非常嚴格,類似在 C 中 void *這樣的儲存是絕對不允許的
    compiler 层面并没有不允许 void*吧?我司就是 void*满天飞。当然更 idomatic 的做法是 std::any

    > 也是搞不懂上面講的 template,一直不懂怎麼在 wrapper class 當中放下那麼多型別的資料,後來才發現需要依賴類似 std::variant 這樣的方法。
    个人觉得使用 variant 的体验远好于 C 的 union 。真的需要管理很多 additive type 的话 compiler 一定做得比我手动去管理来的好
    > ownership 的控制,什麼時候可以用一下 raw pointer 不是什麼地方都要堅持只能用新的 smart pointer
    很少写 C,好奇 C 有这个问题吗? CPP core guideline 建议是不用 raw new/delete, 并没说不能用 raw pointer

    > 得知了 RVO 這樣的東西
    billyzs
        14
    billyzs  
       2020-09-30 05:01:34 +08:00
    @billyzs
    > 得知了 RVO 這樣的東西
    近 20 年的 C compiler 大部分也都实现了 RVO,C++17 不过是把 NRVO 写进了 standard 。左值右值倒是真的有点绕
    msg7086
        15
    msg7086  
       2020-09-30 06:37:51 +08:00
    才到智能指针这些吗?

    再往后看看,C++20 那些花里胡哨的东西,你甚至可以把 C++代码写成 Python with pointers 。
    Mutoo
        16
    Mutoo  
       2020-09-30 06:45:53 +08:00   ❤️ 4
    C++11 之后叫 modern C++,加入了很多新特性,基本上是新的语言了。
    这两个手册可以帮新手解惑
    https://github.com/lefticus/cppbestpractices
    https://github.com/isocpp/CppCoreGuidelines
    Cooky
        17
    Cooky  
       2020-09-30 07:41:43 +08:00 via Android
    学下 Python 放松一下?
    Mithril
        18
    Mithril  
       2020-09-30 08:39:28 +08:00
    C++的套路就是保持静态类型语言的基础不变,功能上尽量向动态类型语言靠拢,估计大佬们也知道动态类型才是生产力。
    不过我已经跟我的之上妥协了,新标准已经啃不动了,只能是 C with Class 这样混日子而已。
    k9982874
        19
    k9982874  
       2020-09-30 08:46:29 +08:00
    先膜拜一下给内核提补丁的大佬。一切设计都是在应对某种场景,一但脱离场景都会很另类。
    不得不说,目前的“现代”编程语言都是在给 C 打补丁,弥补 C 在开发或工程上的不足,包括 C++。
    levelworm
        20
    levelworm  
       2020-09-30 08:47:43 +08:00 via Android
    看 Effective C++,尤其是第二版,会有相当收获。写 C 出身肯定功底不错,习惯 C++也就是时间问题。
    killerirving
        21
    killerirving  
       2020-09-30 09:07:36 +08:00   ❤️ 5
    Go 才是真正的“C++”,C++应该改名 C++++++++++++++++。
    shakespark
        22
    shakespark  
       2020-09-30 09:22:28 +08:00
    c++是真的难,各种语法特性,c++11 及以后就是一门新的语言
    huiyifyj
        23
    huiyifyj  
       2020-09-30 09:26:12 +08:00
    @killerirving @21
    你这是放鱼饵,钓那些骂 go 的人吧?🤣
    bitdepth
        24
    bitdepth  
    OP
       2020-09-30 09:31:09 +08:00 via iPad
    @billyzs
    1. 公司其實很隨便,因為沒人懂。但是在教我的地方這樣寫給他們看,會被幹死
    2. 這邊還要搭配 std::visit 才有用,有點傻眼
    3. C 沒有智能指標,記住要 free 就好了
    4. 昨天大家討論結果是 C 好像是沒有 RVO,而且 Linux kernel 目前還是要求 gcc 8 能編譯過。這樣假設會在 maillist 中被幹死。
    cmdOptionKana
        25
    cmdOptionKana  
       2020-09-30 09:45:45 +08:00
    感觉 C++最大的问题是太灵活了,每个人写出来的风格都很不一样。当初 Java 能在客户端 /业务市场全面制霸,其中一大原因可能就是 Java 死板,大家写出来的风格都差不多。
    zjsxwc
        26
    zjsxwc  
       2020-09-30 09:59:22 +08:00
    c 语言和脚本语言一样自由,一下子切换到强类型无 gc 的现代 c++当然不能适应,逃
    InkStone
        27
    InkStone  
       2020-09-30 10:02:19 +08:00
    我觉得还是按顺序学吧……你一上来就看 concept 和 consexpr 会感觉很奇怪,但如果是从 c++原版,11,17,20 一路看下来,那 concept 简直就是理所当然的……

    同样的,C++很多特性得从 C 里找根源。比如你说的 template 和 macro,vtable 等等
    Chenamy2017
        28
    Chenamy2017  
       2020-09-30 10:06:29 +08:00
    以前没了解过 C++,我倒是觉得需要系统的学习下,C 相对 C++真的是太简洁了。
    paoqi2048
        29
    paoqi2048  
       2020-09-30 10:18:40 +08:00
    其实 C++的很多问题都是兼容 C 兼容出来的
    redme
        30
    redme  
       2020-09-30 10:37:33 +08:00
    ++c
    liukrystal
        31
    liukrystal  
       2020-09-30 12:26:04 +08:00 via iPhone
    上了年纪就真的学不动 C++了,自 11 之后基本上就是一门新语言了,越来越像动态语言。
    janus77
        32
    janus77  
       2020-09-30 12:52:27 +08:00
    我听过一个说法:C++就是因为太自由了,所以才变得太不自由。
    前者是指语言本身,后者是因为前者导致各种不可预期的问题,所以在实际开发中才需要各种严格规定以保证项目的稳步进行。
    arrayJY
        33
    arrayJY  
       2020-09-30 13:10:12 +08:00 via Android
    constexpr metaprogamming 比纯 template metaprogramming 好看多。

    至于 pointer 问题,这就是 Cpp 为了兼容 C 而不得不留的坑,除非有 nullptr 否则我一律当 pointer 不存在
    whorusq
        34
    whorusq  
       2020-09-30 13:41:24 +08:00
    @woncode 不是,听说学了 rust 再来搞 c++ 更 easy
    leavic
        35
    leavic  
       2020-09-30 13:41:37 +08:00 via iPhone
    九评 c++了解一下
    willww64
        36
    willww64  
       2020-09-30 14:46:11 +08:00 via Android
    @luodaoyi 写 Windows 内核?微软大佬 v
    hoyixi
        37
    hoyixi  
       2020-09-30 14:51:52 +08:00
    很多编程语言近 10 年的发展,感觉就是不断地挖坑埋自己。
    缝缝补补,挖个大坑埋几个小坑,挖 10 个小坑埋一个大坑。Node/Javascript 生态圈尤其典型
    hejingyuan199
        38
    hejingyuan199  
       2020-09-30 15:06:46 +08:00
    哈哈,提问者和大部分回答者不在一个层次上,所以看到了一些答非所问。。。
    我觉得楼主的问题只是一些个人心得,而不是提问。。。
    从楼主的问题里,我学到了很多。
    roundgis
        39
    roundgis  
       2020-09-30 15:26:02 +08:00 via Android
    @woncode 比不上 scala 複雜
    c0011
        40
    c0011  
       2020-09-30 15:42:12 +08:00
    @hoyixi 主要是考虑兼容性,我就想这个兼容性不能不考虑吗。。。
    Wirbelwind
        41
    Wirbelwind  
       2020-10-02 01:42:24 +08:00
    3.ownership 的控制,什麼時候可以用一下 raw pointer 不是什麼地方都要堅持只能用新的 smart pointer

    ownership->所有权->让 new 的生命周期和当前 smart pointer 变量生命周期同步

    smart pointer 本身是局部变量或成员变量,通过这样的方式不需要手动 new 和 delete

    ①程序类型结构上出现有循环引用,结构下级保留指向上级的 weak_ptr 或 raw ptr

    ②用到了 c 语言的库,用 smart pointer 管理

    ③需要用指针进行运算的时候,只能用 raw pointer

    4.對 class destructor 的要求,我之前不知道 C++ compiler 會幫忙填充 vtable 和進行 offset 換算的工作,這在 glib 中原本都是要手寫。

    极其不建议写带 virtual 的代码

    ---------------------------------------

    對 compiler 的行為不理解,特別是 object 的處理行為

    写多了就熟悉了,c 是 c,c++是 c++
    impig33
        42
    impig33  
       2020-10-02 11:04:42 +08:00
    @killerirving

    c--不是更好
    tairan2006
        43
    tairan2006  
       2020-10-02 11:32:07 +08:00 via Android
    兄弟,用 go
    secondwtq
        44
    secondwtq  
       2020-10-02 11:56:22 +08:00 via iPhone
    “编译器行为学是 C++ 的特色,不能不品尝”
    user8341
        45
    user8341  
       2020-10-08 21:34:54 +08:00   ❤️ 1
    @cmdOptionKana 没错。C++太灵活了不统一风格不行。很多项目都用《 Google C++ Style Guide 》,不知道大家如何评价?

    像楼主提的最后一个问题:by value or by refer 什么情况用哪个,在 Google 风格指南里就有要求:

    input parameter 用 by value 或者用 const &。
    output parameter 用指针。

    个人认为好处是,从调用函数的地方很容易看出一个变量会不会被函数改变。比如 f(x, &y),很明显 x 不会变,y 会变(因为它取地址,是作为指针传入,必然是 output parameter )。
    user8341
        46
    user8341  
       2020-10-09 10:58:42 +08:00 via Android
    @user8341 发现还是自己看错了。谷歌指南还分把参数分成可选或必须两种。可选的才用指针,因为引用不能传空值。必须的参数就一律用传值或引用。

    是不是说小对象就传值,大对象就传引用呢?
    Wirbelwind
        47
    Wirbelwind  
       2020-10-10 11:55:50 +08:00   ❤️ 1
    @user8341 看个人用法。

    c 用 pointer ( c 没有引用)。c++建议传 reference,要避免出现 raw pointer,写 argument 的时候也不会出现&,如果不修改变量,加 const,否则不加。
    levelworm
        48
    levelworm  
       2020-10-27 01:15:20 +08:00
    @cmdOptionKana 我觉得大公司写 C++的话肯定要有 guide,什么能用什么不能用,否则一些炫技的东西真心吃不消。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2839 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 13:31 · PVG 21:31 · LAX 06:31 · JFK 09:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.