虽然说没有银弹,但是我感觉 c++完全可以设计成更友好,开发速度更快的语言

2021-07-14 21:14:58 +08:00
 zxCoder

c++大佬别杠我,不可否认的是 c++学起来实在太难,写起来实在太慢

实际上很多东西感觉完全可以反过来吸收别的语言的优点

16959 次点击
所在节点    程序员
209 条回复
wctml
2021-07-16 11:03:44 +08:00
使用 C++就是浪费生命,我已经浪费了 5 年了。
ipwx
2021-07-16 11:15:40 +08:00
@levelworm 在任何你想用 new T 并且只有一个人拥有它的地方都能用 unique_ptr 。

至于 shared_ptr,主要是不特定多个持有者要共享同一个对象才会用,这些持有者到底谁先死都不知道的时候还是有必要的。在多线程并发程序里面有时候还是躲不过的,比如 boost::asio
INCerry
2021-07-16 11:16:12 +08:00
@dqzcwxb 这个特性确实很吸引人 虽然造成了吞吐量下降 和 更多的内存占用
ipwx
2021-07-16 11:17:39 +08:00
@ysc3839 @levelworm 另外我觉得 shared_ptr 最合适的场景其实是只读对象或者数据对象。一个对象被创建出来,记录了一些信息,发给多个持有者,这些持有者的生命周期都不一样,并且在错综复杂的多线程环境中。这种时候用 shared_ptr 就很合适。

比如进程里面通过消息队列来传递消息的这种场景。
ipwx
2021-07-16 11:20:05 +08:00
@junkun const char* 可以隐式转换为 bool 这个还真让我踩过。不过一个函数会同时在同样的位置接受这两个类型的参数还真挺少见。
wutiantong
2021-07-16 11:31:31 +08:00
@Austaras
可以看出你非常喜欢 rust,我虽然没学过 rust 不过坦率来说,我挺抵触“在语言层面上显式地定义生命周期”这个 idea 的。
对象的生命周期在 C++里明明已经不是问题了,而这与智能指针没有太大关系,主要是受益于移动语义和 RAII 。
现在在 C++里,对象在定义(不是 new )时诞生,在离开 scope 时自动消亡,并不需要付出多少精力去解决所谓的生命周期问题。
固然这一切有赖于写 C++的人是否真的学会了这些,而一知半解的代价就是引起各种生命周期问题。
但平心而论,rust 并没有真正去简化任何问题,它需要每个人在语法上付出额外的代价来获得一份来自编译器的保护,使得那些一知半解的人即使继续写出有问题的代码,至少不必付出实际代价(无法上线)。
那么在座诸位,你是想继续做一个对生命周期问题一知半解,用丑陋的代码来换取编译器保护的人;还是想做一个彻底攻克生命周期问题,持续写出优雅的代码,并有机会探索更多语法可能性的人呢?
ipwx
2021-07-16 11:39:15 +08:00
@wutiantong 有些人在编程语言上特别执拗,有种宗教狂热的感觉。比如王垠,不是瞧不起非 FP 语言么。安啦安啦
levelworm
2021-07-16 11:40:17 +08:00
@ipwx 可能是我功力比较弱,所以往往会纠结,这个东西到底是不是一个人拥有呢?还是说弄不好写到后面发现要分享了?我总觉得得想好所有的架构才能开始写,所以特别痛苦。裸指针就爽多了,一把梭,反正是自己写的东西,泄漏就泄漏了。
ipwx
2021-07-16 11:41:36 +08:00
@levelworm

1. 想好所有架构开始写,这才是对的。不然你项目规模根本不可能突破一万行。
2. 裸指针一把梭?泄露就泄露?朋友,习惯了这种写法,你项目永远做不大啊。
ipwx
2021-07-16 11:42:39 +08:00
@levelworm 不过裸指针一把梭的情况也是有的,那叫 ObjectPool 对象池。一般用在算法内部分配数据结构节点的时候。先分配一大块内存,用就切,退出函数把大块内存给一起释放。
levelworm
2021-07-16 11:46:32 +08:00
@ipwx 我的项目倒是都不大,比如说自己写的小游戏啊编辑器啥的。不过我其实是想想好再写的,我觉得代码写好是一个工程师的素质体现,哪怕是自己写的玩的。问题是我纯粹是业余写这个,所以写着写着就觉得大脑不够用了。这是我比较苦恼的地方。

还有一个问题是和 C 库结合的问题,比如说 SDL2 。
ppphp
2021-07-16 12:36:26 +08:00
c++语法支持了太多简单,一开始很好理解的小东西,导致本来很简单的小东西合一起用就很阴间很难懂很容易出错,而这种特性太多的问题是没有办法修复的,高级的概念并不能让人很好理解的话,很难淘汰低级的概念
ipwx
2021-07-16 12:50:20 +08:00
@levelworm 用类包一下就好用了
junkun
2021-07-16 13:32:09 +08:00
@wutiantong C++也是有问题的,比如一个对象之前已经被 std::move 了,但 C++不会阻止你去访问一个 move 掉的对象,之后再调用这个对象的行为是一个 UB,相当于一个悬挂指针。
rust 显式定义生命周期的目的,不是为了计算对象什么时候 destroy (这一点 rust 也是 RAII ),而是为了保证你在函数内访问或返回一个对象的引用的时候,这个引用一定是 valid 的。
wutiantong
2021-07-16 13:52:50 +08:00
@junkun

1,访问一个移动后的对象不是 UB,请参考: https://en.cppreference.com/w/cpp/language/move_assignment

2,确实不应该继续使用一个移动后的对象,既然选择了 move 它,就隐含着“不会继续用它了”这样的判断

3,大部分时候移动语义自动发生,较少时候需要手动 std::move(),请参考: https://en.cppreference.com/w/cpp/language/value_category

4,“为了保证你在函数内访问或返回一个对象的引用的时候,这个引用一定是 valid 的”,所以 rust 到处都是对象的引用吗?难怪会变成这样呢。如今用 C++可以大量地运用值语义类型,结合 const & 你都很难看到 new / 指针 / 左值引用,别提多爽了。
no1xsyzy
2021-07-16 13:59:23 +08:00
@wutiantong rust 的复杂生命周期语法在大部分代码中是不需要写的。
而且其实 ponylang 更好,有 GC 但不会 stop the world,因为 GC 只会发生在 pony 代码不运行的时候,反而是如果没写好更可能泄漏(
wutiantong
2021-07-16 14:09:23 +08:00
@no1xsyzy ponylang 是新语言吗?还没怎么听过呢。

我完全理解 “在大部分代码中不需要写”,就好像有些人用智能指针时连 weak 都没弄明白。

毕竟这里很多人连写库与写应用的差异都没有体会。
ipwx
2021-07-16 16:11:39 +08:00
@junkun @no1xsyzy 弱弱的说一句,有个现代 IDE 把关(比如 CLion ),不忽略 IDE 的检查,基本上 UB 对象调用在刚写出来就会标出来。。。 所以只要程序员脑子不出问题,这方面就真不是问题。

如果你不相信你的程序员的脑子,那确实 C++ 不适合。
junkun
2021-07-16 17:36:34 +08:00
@ipwx 我是没看过哪个 c++的编译器能检查悬浮指针的问题的。微软和谷歌这些大量程序员用 c++的公司,都承认改用 rust 后,解决了绝大部分用 c++出现的内存错误。也许是他们的程序员脑子也不行吧。
cheng6563
2021-07-16 17:43:56 +08:00
感觉万恶之源就是兼容 c

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/789560

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX