17611538698
webmaster@21cto.com

5条糟糕的 C++ 建议:OOP、设计模式和堆内存

编程语言 0 49 22小时前
图片

21CTO导读:学习和使用C++,有一部分是编码者自身的原因,并非语言造成的复杂性。这和学任何语言的“道”是相通的。

有一位Youtube作者,近日总结了 5 条糟糕的 C++ 建议。它们分别是:使用 OOP;把阅读 C++ 书籍和编程模式书籍当成写代码的替代品;花太多时间学习高级 C++;把“不按 C++ 预期方式使用就是用错”当成规则,因而到处使用高级 C++;以及把小对象随意分配到堆上。 

这位作者做了 10 年 C++ gamedev,并设计了 5 道问题。答对至少 4/5,他认为你就已经进入程序员前 10%。

1. 把 OOP 用到 Cookie Clicker 上


第一个坏建议是“使用 OOP”。作者并不是说 classes 有问题,使用 structs 也没有错。他反对的是用 OOP mindset 组织所有代码。

一位程序员按照 OOP 原则做了一个游戏,最后写出了 50 个 classes。这个游戏是 Cookie Clicker,而且只是一个没有打磨的大学快速项目。

第一个问题是:一个类似 Cookie Clicker 的游戏,使用 50 个 classes 合理吗?答案是不合理。作者说,他的多人 Minecraft 游戏大概也有 50 个 classes,但项目规模大得多。

作者在视频中对比了 Cookie Clicker 与多人 Minecraft 项目的规模

按照这个比例,如果 Cookie Clicker 需要 50 个 classes,那么一个类似 Minecraft 的游戏可能至少需要 1,000 个 classes。这个案例不是编造的,作者认识做出这个项目的人。

作者的一位朋友后来用几百行 procedural code 重做了这个 Cookie Clicker 游戏。这样一来,整个游戏从一眼就能看懂。相比之下,50 个不同文件、每个文件放一个 class,会让代码更难理解。

类当然有用途。简单代码应该先从一个 function 开始,只有真正需要抽象时再抽象。否则,OOP mindset 会让你在不需要类的地方继续堆类,最后写出过度设计的代码。

2. 用 C++ 书籍和编程模式书籍代替写代码


第二个坏建议,是把阅读 C++ 书籍和 programming patterns books 当成主要学习方式。

作者把编程比作开车。你需要先学会基本的街道标志,但之后想成为好司机,就应该把时间花在开车上,而不是继续读驾驶书籍。

Steve 读过超过 1,000 本驾驶书,却从来没有坐进车里。Antonne 甚至不会阅读,却从 10 岁开始开车。作者问,如果要找人开车送自己回家,你会相信谁?

编程也是一样。每天的时间有限,应该用来写代码和制作大型项目。你会在项目中遇到具体问题,再通过研究小问题学习新内容。

作者对书籍的主要问题是,它们会用很慢的方式教授大量暂时用不到的信息。这些知识也许有价值,但用于制作项目的时间更重要。

阅读 coding practices 的书,也不会直接教会你正确组织代码。作者甚至认为 design patterns 基本上是一种骗局。他说,真正写很多代码、制作大型项目后,你会自己理解这些模式,也会比读书理解得更深。

第二道问题的标准是:你最近是否在挑战高难度项目?如果答案是肯定的,就能得到这一分。如果只是学习编程却不采取行动,包括观看 YouTube 视频后完全不使用里面的信息,就不算真正学习。

作者还提到,YouTube 上的 javidx9 有一些很酷的 C++ 项目,可以作为练习参考。

3. 花太多时间学习高级 C++


第三个坏建议,是把太多时间花在学习高级 C++ 上。

作者在大学时和一位同学讨论 C++ 和 assembly 课程。这套课程对很多学生来说又难又吓人。一位同学甚至说,大学里的 C++ 是自己一生中最难完成的事情。

作者告诉她,自己已经知道大学课程里关于 C++ 和 assembly 的所有内容。她认为作者是在说谎,但她没有考虑两人的学习方向不同。

那位同学已经会 webdev、frontend、backend、databases、入门级 C++,还会其他一些语言。作者则连网页都不会制作,因为他把所有时间都花在学习 C++ 上。所以,他知道更多 C++ 和 assembly 内容并不奇怪。

专注于一件事本身没有问题,但 C++ 的 rabbit hole 非常深。你很容易把全部时间花在奇怪的 C++ quirks 上,而不是写代码。这些内容确实重要,但不应该占据全部时间。

第三道问题的答案也很明确:不要把大部分时间花在学习 esoteric C++ 内容上,而应该把大部分时间用于 coding。

算法和数据结构的额外陷阱


作者还提醒,不要花太多时间学习 algorithms and data structures。他认为 school 和 university 在这些主题上花了太多时间,甚至像是在骗学生。

在他看来,高级算法只在非常具体的场景中有用。他的多人 Minecraft clone 使用过的最复杂算法,基本就是 BFS。整个 codebase 里甚至没有一个 list

4. 把高级 C++ 和模板代码用到每个地方


第四个坏建议是:如果没有按照 C++ 的“预期方式”使用它,那你就是用错了。

作者认为,C++ 基本上是第一个现代语言,大家没有充分肯定它的贡献。但因为它很早加入了许多现代功能,其中很多功能并不好用。当然,也不是所有功能都糟糕,也不是所有时候都不该使用。

你应该了解高级 C++,并在确实需要时使用它。如果不停使用这些功能,codebase 最后会变得无法维护。

std::vector 是最简单的数据结构之一,但作者自己的实现已经很复杂。

作者还展示了自己写的 std::vector 实现

问题在于,看到这样的代码后,你不可能确定自己是否正确实现了它。编译器不会提醒你,代码中还可能藏着你不知道的 C++ edge case。

作者说,标准 vector implementation 有 2,000 行代码。这些代码是为了写出没有 edge cases 的完美实现。如果最简单的数据结构都需要 2,000 行 modern C++,那么一个真正的项目需要多少行?一百万行吗?即使这样,里面仍然可能有 bug。

作者的一位朋友曾经修复过 MSVC 的 standard template library 中的一个 bug。按照他的解释,问题与取地址符号可以被重载有关,这会造成非预期行为。作者在整个 C++ 生涯中从未遇到过这个问题,但这正说明每个细节都可能成为陷阱。

逗号运算符也可以被重载。那是不是意味着不能在 generic variadic code 中使用逗号运算符?作者也不知道,但他认为没有必要为了这种问题让项目变复杂。

如果用 C 写一个 vector implementation,代码会简单得多,也更容易直接看懂。第四道问题的答案是:视频中的那段复杂代码不应该这样写。你不需要一直写 generic code,直接写一个简单的 method 就够了。

制作大型项目时,作者更想把注意力放在如何组织 rendering pipeline,而不是研究 templated code 应该传入哪一种 reference。C++ 的 containers,例如 strings 和 vectors,应该经常使用,因为它们能让代码更简单。

作者说,自己使用 templates 的次数大概是一年一次。高级功能应该服务于项目,而不是让项目服务于高级功能。

5. 把小对象随意分配到堆上


作者在 C++ 代码中最常看到的问题之一,是错误地分配内存。

最后一道问题给出了一段代码,并询问其中有什么问题。这是一个陷阱。你可能会说,player 应该放进 unique pointer。少做内存管理当然更好,但更好的答案是:根本不要分配它

作者不理解为什么有人会随机把东西分配到 heap 上。有人分配完所有对象后说,使用 smart pointers 就没问题了。但这只增加了复杂度。

他用一个比喻说明这一点:去 Sahara desert 时带上一件 winter jacket,然后说“没关系,背包会帮我带着它”。真正的做法是不带这件 jacket。

视频中的这个 struct 并不大,所以不应该放到 heap 上。许多初学者把小对象放到 heap 上,以为这样能加快复制,或者防止意外复制。但这两种想法都不对。

到处分配内存会严重影响性能,让代码变慢。更重要的是,如果所有东西都变成 pointer,代码最终会变得很糟。Pointers 是工具,应该在需要时使用,而不是随机放在所有地方。

作者查看别人的代码时,经常看到到处都是 pointers。它们本来就不应该出现在那些地方。作者自己的代码里很少看到 pointers,不是因为他刻意避免,而是因为很多时候根本不需要。

视频最后展示了这个内存分配问题。关于更多细节,作者还推荐了 How to manage memory in C++。还用 Terraria-like 游戏完成第一个大型 C++ 项目。

如果你是 beginner 到 intermediate 的 C++ 学习者,并想完成自己的第一个大型项目,可以查看作者的 C++ gamedev course for beginners。课程包含 6.5 小时视频内容和 50+ guided challenges,学习者会和作者一起制作一个 Terraria-like 游戏。

作者说,许多课程只让学生 copy paste,而这门课程要求自己练习;课程也不是只 live coded,而是经过 scripted 和 edited,以提供更好的讲解,页面可能还有 special discount。

作者:洛逸

来源:

https://www.youtube.com/watch?v=hQP_--GLIiA

评论

我要赞赏作者

请扫描二维码,使用微信支付哦。

分享到微信