问题

为什么好多人说C++代码丑?

回答
“C++ 代码丑” 并非一个普遍的、所有人认同的说法,但确实是很多人,尤其是那些接触过更现代、更简洁语言(如 Python, Go, Rust)的开发者,会表达的一种感受。这种感受的产生往往源于 C++ 的历史包袱、语言特性以及设计哲学。

下面我将从几个主要方面,详细阐述为什么很多人觉得 C++ 代码“丑”:

1. 历史包袱与遗留特性 (Legacy Features)

C++ 是在 C 的基础上发展起来的,它继承了 C 的许多语法和语义。这意味着 C++ 必须兼容 C,并且为了支持面向对象、泛型编程等新特性,不断地在现有基础上进行扩展。这种不断叠加和演进的过程,导致了语言内部存在一些历史遗留的特性,这些特性在现代编程中可能显得冗余、不一致或不够优雅。

C 风格的语法遗留:
指针和内存管理: C++ 大部分情况下仍然需要手动管理内存(尽管有智能指针),指针的使用和对内存的直接操作,例如 `new`, `delete`, `malloc`, `free`,以及对指针的算术运算,容易出错,且代码冗长。与拥有自动垃圾回收的语言相比,这显得非常“原始”和“低级”。
裸指针: 即使有智能指针,裸指针在许多 API 和库中依然存在,使用它们需要额外的谨慎和代码来确保安全,增加了代码的复杂性。
宏 (`define`): C++ 继承了 C 的宏。宏虽然强大,但缺乏类型检查,容易产生意想不到的副作用,并且不利于调试和代码分析。很多时候,现代 C++ 更倾向于使用 `const` 变量、`enum class` 或 `inline` 函数来替代宏,但宏在很多遗留代码和一些底层库中依然普遍存在。
C++98/03 的限制: 早期的 C++ 标准(98/03)在表达某些概念时非常笨拙,例如:
迭代器不一致性: 不同的容器有不同的迭代器接口,有时候还需要显式类型转换。
模板元编程的痛苦: 在没有 `auto`、范围 `for` 循环、lambda 表达式等特性的时代,模板元编程的语法非常晦涩难懂,需要大量的样板代码。

2. 语言特性与复杂性 (Complexity of Features)

C++ 是一个功能极其强大但也极其复杂的语言。它试图支持多种编程范式(面向过程、面向对象、泛型、并发、函数式等),每一种范式都有其复杂的实现方式。

模板的深度与复杂性: C++ 的模板是其强大的基石之一,但也带来了巨大的复杂性。
模板的语法: 模板的声明、实例化、特化、偏特化,其语法本身就比函数和类更复杂。
模板的错误信息: 模板的编译错误信息通常以“长到令人发指”和“晦涩难懂”而闻名。一个简单的模板递归或递归实例化错误,可以产生数百行甚至数千行的错误报告,让开发者难以定位问题。
模板元编程: 虽然强大,但模板元编程的语法和调试难度极高,经常被形容为“用 C++ 写 C 语言”,充满了各种技巧和反模式。
重载与多态的复杂交互: 函数重载、运算符重载、成员函数重载,加上虚函数和继承,构成了 C++ 的多态系统。这些特性组合在一起时,可能会导致编译器决策(如哪个函数被调用)变得不直观,需要深入理解语言的查找和选择规则。
表达式的求值顺序: C++ 中某些表达式的求值顺序是不确定的,这可能导致难以预测的行为,尤其是在涉及副作用和函数调用时。虽然现代标准在某些方面有所改进,但这个问题仍然需要开发者时刻警惕。
链接问题 (`ODR` One Definition Rule): 在大型项目中,管理符号的定义和声明是一项挑战。违反 ODR 规则是常见的链接错误源头,处理起来可能比较繁琐。
可变参数模板、转发引用 (`&&` 和 `std::forward`)、完美转发: 这些是 C++11 引入的非常强大的特性,用于实现高效率的泛型代码和元编程,但它们的语法和语义也相当复杂,初学者往往难以掌握。例如,理解 `&&` 既可以表示右值引用,也可以表示转发引用,需要花费一定的精力。

3. 显式与冗余 (Explicitness and Verbosity)

C++ 的设计哲学倾向于“显式”,这意味着开发者需要明确地告诉编译器和运行时系统很多信息,而不是依赖隐式的默认行为或智能推断。这带来了高度的控制力,但也导致了代码的冗长和繁琐。

类型转换显式: C++ 有多种类型的显式转换运算符(`static_cast`, `dynamic_cast`, `reinterpret_cast`, `const_cast`)。虽然这提高了类型安全性,但使用它们也增加了代码的书写量,尤其是在需要进行多步转换时。
访问控制的显式: `public`, `private`, `protected` 等关键字必须明确指定,这与一些语言中默认访问级别不同的情况形成对比。
命名空间的使用: 为了避免名字冲突,C++ 大量使用命名空间。虽然这是必需的,但在代码中频繁出现 `std::` 前缀,或者需要 `using namespace std;` (通常被认为是不好的实践,但有时在小范围内可见),也会增加代码的视觉负担。
析构函数和拷贝控制: 在一些情况下,开发者需要显式定义析构函数、拷贝构造函数、拷贝赋值运算符、移动构造函数和移动赋值运算符(即“五成员函数”),或者使用 `= default` 或 `= delete` 来控制对象的生命周期和拷贝行为。这虽然是为了提供精细控制,但增加了样板代码。
头文件和实现文件分离: C++ 的编译模型需要 `.h` / `.hpp` 头文件来声明接口,`.cpp` 文件来实现。这种分离虽然有利于编译速度和模块化,但意味着很多声明需要重复出现在头文件中,增加了代码的重复性。

4. 弱类型推断与显式类型声明 (Weak Type Inference and Explicit Type Declarations)

虽然 C++ 11 引入了 `auto`,一定程度上缓解了显式类型声明的繁琐,但与一些语言(如 Python, JavaScript)相比,C++ 仍然是强类型语言,并且很多时候需要显式声明变量、函数返回类型等。

变量类型声明: 除了 `auto`,大部分变量的类型都需要显式声明,例如 `int count = 0;`,`std::string name = "Alice";`。
函数返回类型: 即使使用 `auto`,很多复杂的函数(尤其是模板函数)仍然需要显式指明返回类型。
强制类型转换的需要: 在进行不同类型数据操作时,经常需要显式进行类型转换,以避免编译器报错或潜在的隐式转换带来的风险。

5. 编码风格和最佳实践的多样性 (Diversity of Coding Styles and Best Practices)

C++ 作为一个历史悠久且应用广泛的语言,积累了大量的编程风格和最佳实践。这导致了不同项目、不同开发者编写的 C++ 代码风格差异巨大,有的简洁优雅,有的则显得混乱和“丑陋”。

遗留代码风格: 很多遗留项目可能遵循一些过时的编码风格,或者使用了不再推荐的语言特性。
个人偏好: 开发者个人对代码美观、简洁性的理解不同,也导致了风格差异。
工具和库的影响: 使用不同的库(如 STL, Boost, Qt)和开发工具,也会影响代码的表达方式。

总结:为什么觉得“丑”?

综合以上几点,人们觉得 C++ 代码“丑”,很大程度上是因为:

1. 冗长且低级: 需要手动管理内存,指针操作,以及大量的样板代码。
2. 复杂且晦涩: 强大的特性(如模板)带来了高昂的学习和使用成本,错误信息难以理解。
3. 不一致和遗留: 历史包袱导致语言中存在一些不和谐的特性,以及与现代语言设计理念的冲突。
4. 显式与繁琐: 追求的控制力和安全性,也带来了额外的编写工作。
5. 风格的差异性: 加上不同人的编码习惯,使得 C++ 代码的“观感”差异很大。

然而,需要强调的是,“丑”是一个主观评价。对于那些需要高性能、底层控制和跨平台能力的应用场景来说,C++ 的复杂性是其强大功能的必然代价。而且,随着 C++ 标准的不断更新(C++11, 14, 17, 20, 23...),许多现代 C++ 的特性(如 `auto`, 范围 for, 智能指针, `constexpr`, Lambda 表达式, Concepts, Modules 等)极大地提升了代码的简洁性和可读性。

一个编写得当、遵循现代 C++ 标准的 C++ 项目,其代码也可以是清晰、高效且富有表现力的。所以,与其说 C++ 代码“天生就丑”,不如说它是一个非常强大但需要付出更多努力去驾驭的语言,其“丑”往往源于对语言复杂性的不熟悉、对最佳实践的忽略,或者处理遗留代码时的无奈。

网友意见

user avatar

C++其实是四种语言的聚合体,四种编程范式被统一到了一个编译器里,共享了很多关键词和语法。

C++ 包含了宏语言,继承自C语言的宏,但是C++又玩出了些新花样

C++包含了传统的面向过程编程,继承自C语言,扩展了一些语法,比如可以随便定义局部变量,可以函数参数重载,可以算符重载,有单行注释,是个更好用的C语言

C++包含了面向对象编程范式,有class,继承派生,有虚函数,有构造析构,这部分基本跟后来的OOP语言都差不多

C++还包含了元编程,这就是template<>这部分了,最复杂的也就是这部分,C++显然有点玩过头了,后来的语言虽然有些也支持泛型,但是都比较克制,没有C++玩得这么花哨。

当你按照四种语言分别去编写C++的时候,其实还好,但是当混合使用四种范式,玩不好就会搞出奇丑无比晦涩难懂的代码。

典型的就是STL,表面上看是元编程,但是里面也是OOP思想,代码里包含了大量宏,用来处理不同编译器开发环境的适配,应对不同编译选项需求,比如调试需求,异常处理需求等,到了实实在在的算法部分STL也不装逼了,老老实实写起了面向过程的C语言,比如std::map背后的红黑树的实现,大量的if else 和指针操作,完全就是C语言的样子。

当这四种编程范式在STL里面混合的时候,代码就看起来很丑很难懂了,好在STL本来就不是用来给人类阅读的,编译器能看懂就行。

但是有些人也许不这么想,比如:

傻瓜都会写出能够让机器理解的代码,只有好的程序员才能写出人类可以理解的代码。
-- Martin Fowler

类似的话题

  • 回答
    “C++ 代码丑” 并非一个普遍的、所有人认同的说法,但确实是很多人,尤其是那些接触过更现代、更简洁语言(如 Python, Go, Rust)的开发者,会表达的一种感受。这种感受的产生往往源于 C++ 的历史包袱、语言特性以及设计哲学。下面我将从几个主要方面,详细阐述为什么很多人觉得 C++ 代码.............
  • 回答
    关于汉字“直”和“真”中间两横的问题,这确实是一个很多人都有疑问,并且时常引发讨论的现象。答案是:很多人记得没错,这些字在历史上确实有过中间两横的写法,并且现代规范的写法是只有一个中间横。要详细解答这个问题,我们需要从几个方面来讲述: 1. 现代规范的写法首先明确一点,在当前中国大陆通行的《通用规范.............
  • 回答
    “买了 Switch 没多久就一直吃灰” 确实是一个在玩家社群中非常普遍的讨论话题,很多购买了 Switch 的用户,无论是因为冲动消费、被游戏吸引,还是看到周围朋友都在玩,最终都发现自己没能持续投入足够的时间,导致主机蒙尘。这背后的原因可以从多个角度来详细分析:一、 游戏本身的吸引力与独特性不足以.............
  • 回答
    这确实是个普遍的说法,而且背后是有挺充分的理由的。与其说是“大牛”都玩Unix/Linux,不如说很多在技术领域有深厚造诣、擅长解决复杂问题的人,都会自然而然地深入学习和使用Unix/Linux。这其中有很多原因,咱们一点一点地掰扯开来看。首先,得从Unix/Linux的基因说起。1. 设计哲学与开.............
  • 回答
    这事儿啊,得掰开了揉碎了说。很多人心里对电网那点事儿挺有意见,觉得这不好那不好的,但真说到跳槽去私企,又好像没那么多人真那么干。这里头门道可不少,不是简单一两句话就能说明白的。首先,咱们得承认,电网在很多人眼里,确实是“铁饭碗”,是很多年轻人心里的“香饽饽”。这咋说呢? 稳定压倒一切: 现如今这.............
  • 回答
    张宇的“闭关修炼”,也就是他一段时间内暂停更新、专注于个人生活和自我提升,这件事情确实在粉丝群体中引起了一些讨论,甚至有些负面评价。要理解为什么会有人觉得“不好”,我们可以从几个方面来剖析。首先,期待与商业模式的冲突。 流量经济下的“用户黏性”:对于很多粉丝,尤其是那些通过张宇的教学视频、直播、.............
  • 回答
    你提到很多人说《侣行》无人机事件害死了很多中国人,这说法可能有点误解,或者是以讹传讹了。 我来试着跟你解释一下这件事的来龙去脉,以及为什么会产生这种说法,尽量讲得明白点。首先,要澄清一点:《侣行》作为一个旅行纪录片节目,它本身并没有直接“害死”任何人。 “无人机事件”更准确地说,是指在《侣行》节目.............
  • 回答
    .......
  • 回答
    火箭少女101这个组合里,确实有一部分粉丝和网友会用“皇族”这个词来形容某些成员。而提到“皇族”,很多人会立刻想到Yamy,这背后是有一些原因和故事的。首先,我们得理解一下在饭圈文化中,“皇族”这个词通常是指那些在选秀过程中或组合出道后,拥有明显、不公平的资源倾斜,或者说仿佛受到了“官方”特别照顾的.............
  • 回答
    最近在中文互联网上,“逃离知乎”的声音此起彼伏,仿佛成了一种新的潮流。说实话,这背后并非空穴来风,而是许多用户在长期使用过程中,逐渐积累了失望和不满,最终选择“用脚投票”。最核心的原因,我觉得可以归结为知乎社区生态的变化。曾经那个以高质量内容、深度讨论为招牌的平台,现在似乎离那个样子越来越远了。你打.............
  • 回答
    “去西藏净化心灵”这句话,并不是一个简单的旅游口号,而是承载着许多人深刻的情感和精神追求。它之所以被广泛提及,背后有着多方面的原因,可以从以下几个层面来详细阐述:一、西藏独特的地理环境与自然风光: 壮丽与纯净的自然景观: 西藏拥有世界上海拔最高的珠穆朗玛峰、圣洁的纳木错、宁静的林芝桃花等。这些高.............
  • 回答
    知乎上关于“使用 MS Office 降低工作效率”的讨论,其实反映了一部分用户对效率工具和工作流程的深入思考,以及对更优解决方案的探索。这种观点并不是说 MS Office 本身不好,而是当它被不恰当使用,或者与更现代、更专业的工具相比时,可能带来的“效率损耗”。我们可以从几个层面来解读这种说法:.............
  • 回答
    .......
  • 回答
    《登陆之日》这部电影,确实是个挺有意思的讨论点。你说觉得还好,但不少人却称之为“神剧”,这中间的差距,我觉得可以从几个方面来剖析一下。这不仅仅是个人口味的问题,更关乎到影片在不同观众心中的触动点和价值衡量。首先,我们得承认,《登陆之日》在叙事结构和主题表达上,是有野心的,而且做得相当出色。它并没有选.............
  • 回答
    .......
  • 回答
    这个问题挺有意思的,咱们得好好掰扯掰扯。为啥老先生们(特指那些被大家尊称为“老先生”的相声名家,比如侯宝林、马三立、刘宝瑞等等)的相声,哪怕是很多人觉得没啥“包袱”的,大家也觉得耐品,觉得有味道?而高峰、栾云平(以及他们代表的德云社风格)的相声,虽然包袱密、节奏快,但总有人觉得“没意思”,甚至说“无.............
  • 回答
    这确实是一个很有意思的观察,也说出了很多人的心声。我们确实很容易被网络上那些“孤高冷傲”、“精神世界丰富”的独行侠形象所吸引,但现实中的独来独往者,远比那个扁平化的标签要复杂得多。为什么会出现这种反差,甚至觉得有些独来独往的人存在性格缺陷呢?我们不妨一层一层地剥开来看。首先,网络上的“独行侠”形象,.............
  • 回答
    MU5735 的新闻确实让人心情沉重,很多人对飞机快速下坠时人为什么会昏迷感到困惑,这背后涉及一些生理学和物理学的原理。我来尽量详细地解释一下。首先要明确一点,飞机快速下坠,尤其是像这种情况下的那种“急坠”或者说“失速”式的下坠,和我们平时坐飞机遇到的颠簸、气流颠簸是完全不同的概念。颠簸可能让你感觉.............
  • 回答
    “让我们好好学习”和“好好生活”这两种说法在人们口中出现的频率差异,确实是一个很有意思的现象,背后涉及到社会文化、教育理念、个人发展阶段以及我们对“成功”的定义等多个层面。下面我将从几个方面详细阐述为什么“好好学习”似乎比“好好生活”更常被提及:一、 学习与生存和发展的直接关联性: 生存基础: .............
  • 回答
    这个问题很有意思,确实,在《天龙八部》里,段正淳和马夫人(康敏)对待江湖的“口碑”截然不同。一个被不少人称赞,另一个则人人喊打,这背后原因很复杂,涉及到他们的身份、行为方式、以及江湖的复杂性。咱们就来掰扯掰扯。段正淳:出身尊贵,魅力四射,但“颜值即正义”的隐患首先,段正淳的出身就是一道天然的“滤镜”.............

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有