# [雅望停云] 用class写C的我


# A Conversation

> **Kakurin**: Pure C as opposed to C++. No idea why. Please don't talk about portability, it's BS.
>
> **Linus**: YOU are full of bullshit. C++ is a horrible language. It's made more horrible by the fact that a lot of substandard programmers use it.

---

# 自我分析

昨日拜读陈皓先生的博客，仿佛被卡密尔精准礼仪般的真实伤害击中，让我在屏幕前陷入了长久的沉思。这不仅是对自己知识体系的反思，更像是一场自我认知的洗礼。感触颇多，一方面反思了自己的学习路径，另一方面也在思考未来的成长方向。

其中有一句话对我冲击最大，一针见血地让我意识到自己的愚蠢：

> 对于大多数自称熟悉C++的程序员来说，基本上他们都是用C++的语法在写C。

这句话精准地描述了我的现状——我写的代码，基本上只是用C++的 class 完成纯C也能实现的功能。我的所谓“封装”只是形式上的，远未真正理解并运用C++的精髓。C++之所以存在并流行，正是因为它能解决C不擅长的问题，而我却依然用C语言的思维去设计和实现，仅仅披上了一层面向对象的外衣。既然如此，为什么不直接用Python？它的开发效率更高、成本更低，而我的应用场景也并无严格的性能要求。过去我总以“通过这种过程可以熟练掌握语言”为借口，但事实上，不跳出舒适区就不会有提升。天天写这种“垃圾程序”有什么意义？美其名曰实践，实际上只是浪费时间，在重复自己会的东西，不敢迈出步伐去学习新知。这张图，这句话，无情地撕下了我用来搪塞自己的遮羞布。没有过硬的本领，又怎能在未来的竞争中立足？

事实上，社区中一直有“C++非常难学”的观点。过去我对这一点的理解非常表面，仅停留在“C++可以用来写游戏引擎、操作系统、高频交易系统”等模糊概念上，这种停留在表象的认知无疑是危险的。学会了类就以为自己学会了C++，多么愚蠢。没有时间根本不是借口，我每天浪费了太多时间在刷手机、做无意义的事情上。我应该静下心来读书，把手机和电脑都丢到十米之外，远离一切电子产品，沉淀下来去学习。或许，就从明天开始吧！

唉，要学的东西还有很多很多，长路漫漫。

想起陈浩先生博客中摘录的Chaucer所言：“The lyf so short, the craft so long to lerne.”（生命如此短暂，技艺如此漫长。）

---

# 观点摘录

> **C++ 学习"自信心曲线"**：
>
> 用 class 写 C 程序
> → 模板类的编译错误让人摸不着头脑
> → 引用类型好像有点神奇
> → Virtual 的析构函数是什么鬼玩意
> → 异常的规格说明和 Java 的相比来说太扯了
> → Static 对象初始化到程序内存错误
> → 好吧，我们需要一定的编程规则

>程序员在一开始学习C++的时候，用C++的语法写C觉得很牛，也会觉得自己很快掌握了C++语言，对一切都充满了信心。他们告诉你他们懂C++，其它他们错误，但我们不能说他们在撒谎，因为人总是不知道自己不知道什么。此后，当他们在C++的学习历程中，发现了很多很多稀奇古怪的东西，还有很多相当底层和复杂的东西，他们的将会变得很受挫，很沮丧，还始变得怀疑起，自信心开始下降，甚至有时候他们靠人品来编程。只到有一天，开始开窃，觉得C++的世界不能乱来，需要一定的规则，一定的方法，于是通过大量的错误不停地总结和反省，最终自信心又会被建立起来，经历多年的历练后，才能恢复自信。

以下陈皓先生关于C++的学习建议：
> C++是最难的语言。这个世界上最难的编程语言可能非C++莫属了。你千万不要以为几天就可以学好C++，C++的学习曲线是相当BT的，你可以看看这篇文章。C++是一门很自由的语言，自由到了有点BT和恐怖的地步。我甚至认为C++并不是一门成熟的编程语言，因为太容易犯错了。所以，你一定要在一开始就要有很小心谨慎的态度，并把C++当成一种难以训服的猛兽来看待。

> 多问“为什么要这样”的问题。学习C++一定要多问几个“为什么是这样”，“凭什么要这样”的问题。比如：很多人知道C++有拷贝构造函数和初始化列表，但你真的知道为什么要有拷贝构造函数？为什么要有初始化列表吗？为什么要有template，为什么要有RTTI，为什么不是别的呢？难道就是为了让一门语言变得Cool一些吗？完全不是这样的，C++中的任何一个feature都有些实实在在的原因，你一定要去了解为什么要把C++设计成这样的原因，你才能学好C++。有空看看《C++演化和设计》一书。

> 看书，大量的C++书。你可以按如下先后顺序阅读（下面这些书，我花了大约4-5年的时间，今天我还在随时温习）  
> 《C++ Primer》，这本初级读本可能让会你啃得很痛苦，所有的语言的特性和为什么都在里面了，好好读读。当然由C++之父写的《C++程序设计语言》也不错。两本看一本就好了（我看的是前者）。  
> 了解C++的语法仅仅是万里长征的第一步，你还需要看看《Effective C++》和《More Effective C++》这两本书并不厚，但我从02年就一直看到现在，每次读我都有新的体会，这两本书太经典了。如果你对C语言不熟，这两本书会让你回去补C语言的课。  
> Think in C++同样是另一本经典之极的书，学c++必读，但是中文版的翻译的很不好，所以还是去读英文版的吧。  
> 《C++沉思录》同样非常值得一读，这里教的不是编程，而是思考的方法，这是相当珍贵的。  
> 《Exceptional C++》和《More Exceptional C++》让你看看各种问题的解决方法和一些常见的经典错误。  
> 《Advanced C++》和《Modern C++》可以让你知道C++各种神奇的用法。  
> 《泛型编程与STL》是把C++实践到了极致的东西。很强大。STL——神一样的模板库（容器，算法和函数对象），不得不服。  
> 《深入探索C++对象模型》让你了解编译器下的C++是什么样的，让你了解C++的性能并不差。这个对于C++的程序员太关键了。我以前写过的《C++虚函数表解析》还有《C++对象内存布局》属于这个范畴。

> 和Java语言做对比。我个人以为Java对C++这个并不成熟的语言做了很多调整，规范和限制。所以，对比一下Java和C++，想一想，为什么一些东西在C++中可以做，但在Java中却不行。比如：Java的异常是必需要catch的，不然就会编译不通过。为什么Java不提供操作符重载？为什么Java会引入接口来做多重继承？为什么Java没有像C++那样的I/O字符流？为什么Java不支持指针？为什么Java可以做到垃圾回收？等等。Java体现着很多面向对象设计的东西，学习Java有助于你学会怎么更好地使用C++来编程。

> 面向对象设计。虽然面向对象可能是个骗局。但是我觉得面向对象设计中的一些实践非常的不错，比如，单一原则，依赖倒置原则，等等，都非常地经典。《设计模式》必需一读，《面向对象的分析和设计》可以一读。但不可以设计模式为中心来编程，而应该是用设计模式来解藕。

> 类库学习。看看MFC是怎么封装Windows API的，看看ACE是怎么面向对象的，看看boost是怎么玩面向对象的，看看CPPUnit又是怎么设计的。当然，Java的JDK中有太多的设计模式，可以参考。

以下是陈皓先生的一些观点：
> 他们习惯于获取大量的知识，而从不对这些知识进行思考和总结。
> 没有思考过，就不算真正的懂，没有思考过，你将无法应对万变的问题，没有思考过，你将成为书呆子。
> 多多实践而不是研究。
> 我们的教育的确很“废柴”，但这不是我们成为“废柴”的原因。
> 我们身边有很多很多优秀的人，网上有很多优秀的文章，书店里也有很多不错的书，而且我们的软件开发日趋成熟，如果我们还学不好的话，那么我们就是在犯罪！

陈皓先生已于2023年5月离世，向他致敬。

---

# TODO 
> Shit, here we go again. - Carl Jason
既然我只是在用C++的语法写C，那么我就再次从C语言出发吧。学习任何东西给我的感觉都是常看常新，学海无涯。There is always more to learn.
书单（暂时先把这些看完吧）：
[ ] 《The C Programming Language》
[ ] 《Algorithms in C》
[ ] 《算法导论》
[ ] 《C++ Primer》
[ ] 《Effective C++》
[ ] 《More Effective C++》


