AICon 上海站|日程100%上线,解锁Al未来! 了解详情
写点什么

C++:后现代的系统编程语言

  • 2016-02-05
  • 本文字数:2343 字

    阅读完需:约 8 分钟

C++ 作为一门经典的编程语言,从上世纪八十年代起至今一直被广泛应用在系统开发和高性能计算领域。近几年来随着各种编程语言和范式的兴起,C++ 的身影渐渐淡出了人们的视野。但是作为一个仍在不断进步的语言,C++ 在最近几年飞速发展,已经具备了现代语言应有的特性,而且也有了许多已有的和正在进行的新的拓展。

经典的 C++

作为 C 语言的超集,一方面,C++ 集成了 C 在系统编程优点,能够精确的控制内存中的每一个 bit;另一方面,提供了丰富的抽象机制和编程范式,引入了面向对象、泛型编程和函数式编程等风格。因为这一点,C++ 拥有了与 C 媲美的运行时性能,另一方面,也简化了 C 语言带来的领域建模的难度。但是因为 C++ 的整体设计结合了多种风格,几乎相当于嵌套了几个小语言的一个庞大的系统,这也使得 C++ 的整体易学性和易用性上有些差劲。同时,由于标准库更新跟不上需求,在诸如 Concurrency/Network 等应用层的软件设计方面逐渐被 Java 等后来者取代。而且,各个 C++ 厂商对编译器的实现并没有完全参考 ISO 标准,也造成了很多跨平台可移植性和兼容性问题。

现代 C++

C++ 在最近几年进行了几次探索和蜕变,让整个语言变得更具备现代化的特色。

资源管理

RAII(Resource Aquiration is Initialization,资源获取即初始化)作为 C++ 的特色之一,被广泛地应用到 C++ 的程序中。RAII 通过堆对象的生命周期来控制资源(包括堆内存、文件句柄、网络连接等)的生命周期,使得资源管理变得更加自动化,同时也避免了引入垃圾回收带来的运行时负担。但这种模式有一个很重要的问题,就是当需要对资源进行共享时,需要做更多额外的工作来进行检查和同步等工作。

作为更现代的资源管理方式,C++11 中引入了两种智能指针,std::shared_ptrstd::unique_ptr。前者拥有线程安全的引用计数,后者则是通过所有权(owenrship)转移来控制资源的生存周期。C++11 中也引入了右值引用和移动语义,来避免资源传递的过程中的不必要的复制。

与 Rust 中的生命周期(Lifetime)和所有权(Ownership)的概念类似,C++ 的std::unique_ptr在每一次值传递的时候将自身持有的资源转移到赋值的目标,同时结合移动语义,将赋值过程进一步地优化。

Lambda

Functor 作为 C++ STL 的一个重要组件,也是 C++ 中被使用很多的一个功能。一个 Functor 其实就是一个重载了operator()的类的实例对象,这种对象配合 C++ 模版的行为,可以被简单看成一个函数来调用,所以被称为 Functor(函子)。但是,由于 C++ 对于匿名类和内部类支持并不够好,使用 Functor 必须提前进行设计。一方面不方便使用,另一方面,定义和使用分离,对代码的组织和理解也造成了一定的困难。

首先,lambda 作为 Functor 的替代品,解决了不能即时定义并使用的问题。配合 STL 中的容器和算法,lambda 也能将 C++ 的函数式风格发挥到极致。其次,出于 C++ 一贯对性能和抽象的考虑,引入了 lambda capture 的概念,使得对象的生命周期能够绑定到 lambda 表达式,也就能够构建出闭包对象(closure)。另外,C++14 中加入的 generic lambda,增强了 lambda 的类型推导算法,在不损失类型安全特性的基础上,让组合式编程(Combinator–based Programming)更加易于实现。

并发

在 C++ 设计的初期,并发并未作为核心的语言特性考虑在内。并且,线程等并发模型在不同平台之上也有各种不同的实现,构建一个统一的并发模型也很困难。

C++11 中重新设计了 C++ 的内存模型,在保持原有兼容性的基础之上加入了并发的内容。同时标准库中也加入了线程(<thread>)、信号量(<condition_variable>)、互斥锁(<mutex>)和原子操作(<atomic>)等内容。同时也在此基础上封装了future/promise模式和async等操作。

元编程

C++ 自身对元编程提供了良好的支持。作为主要组件之一的模版,提供了编译时的数值计算和类型计算。但一方面由于使用模版减慢编译速度,另一方面,在使用模版的时候,非常难以调试和排错,这让很多人望而却步,甚至对基于模版的 STL 组件也有一种畏惧感。

C++11 中对元编程支持做了加强。首先是把 type traits 作为标准库引入,能够给模版提供一套直观的约束,也让类型作为 C++ 中的第一类值(first-class value)存在;另外 constexpr 的引入简化了编译时的值运算,配合用户自定义字面量(user-defined literals)以及可变参数模版(varadic template/parameter pack)等特性,让 C++ 能够更方便地定义内部 DSL。

Bright Future

作为一门经典的编程语言,C++ 至今还在不断地更新着。即将到来的 C++17 中,正在筹备着这些重要的特性:

  • 更丰富的标准库:C++ 中对 File System、Network 等重要的组件进行了标准化的支持,
  • Module TS:模块化提案,用于替代继承自 C 语言的头文件,简化 C++ 的编译模型和模块依赖,
  • Concepts TS:用于增强类型约束和类型推导,同时也简化模版的用法,
  • Reflection TS:提供编译期静态反射的支持,简化和增强 type traits,提供更丰富的元编程功能。

Conclusion

可以看到 C++ 发展至今一直都走在时代的前列线上。一方面,增加了更多适合应用和系统开发的组件,另一方面,通过语言特性的扩充来简化抽象复杂度。作为这样一个兼具新生特性和历史责任的编程语言,足以预见其应用的广度;同样,更多的系统级开源项目,像 Mesos 等,也选择 C++ 作为主要的编程语言。有足够的理由让我们相信,C++ 正在重获新生。

编后语

《他山之石》是 InfoQ 中文站新推出的一个专栏,精选来自国内外技术社区和个人博客上的技术文章,让更多的读者朋友受益。本问转载自《TW 洞见》。文章推荐可以发送邮件到editors@cn.infoq.com。


感谢魏星对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

2016-02-05 17:115504

评论

发布
暂无评论
发现更多内容

给 SAP BTP 创建的 Java 应用添加 Custom Event Handler 支持创建功能

汪子熙

spring 云原生 Cloud SAP 10月月更

流程引擎的架构设计

京东科技开发者

架构设计 报表 workflow BPM 流程引擎

开源无国界,从openEuler Maintainer到Spark Committer的贡献开源之路

openEuler

spark 开源 openEuler

【LeetCode】合并两个有序链表Java题解

Albert

算法 LeetCode 10月月更

SAST + SCA: 结合使用安全升级

SEAL安全

SCA 安全测试 攻击 SAST 应用安全测试

国产分布式数据库发展趋势与难点

亚信AntDB数据库

AntDB 国产数据库 AntDB数据库 企业号十月PK榜 企业号十月 PK 榜

数字化背景下,低代码发展的动力和阻力

飞算JavaAI开发助手

web丨nft元宇宙链游项目系统开发模式逻辑详细(成熟源码)

I8O28578624

量化与科技的相遇!亚马逊云科技揭开神秘的量化私募

Lily

前端技术培训后的职业规划

小谷哥

带你认识JDK8中超nice的Native Memory Tracking

华为云开发者联盟

开发 华为云

华为云确定性运维,为政务云平台稳定可靠运行保驾护航

华为云开发者联盟

云计算 华为云 政务云 企业号十月PK榜

分享一个好问题:企业为什么要区分数据中台和数据平台?

雨果

数据中台 大数据平台

32天高效突击:狂刷《Java权威面试指南(阿里版)》,offer拿到手软

Geek_0c76c3

Java 数据库 开源 程序员 架构

java培训机构口碑排名哪家比较好?

小谷哥

数据分析师被当作取数机怎么办?

雨果

数据中台 数据分析师

聚焦六大典型应用场景,博云金融行业容器解决方案更新发布!

BoCloud博云

云计算 云原生 容器云

前端培训怎么学习好就业?

小谷哥

数据中台选型前必读:数据中台与大数据平台有什么区别

雨果

数据中台 大数据平台

单刷 3 届 Hackathon,朝着理想中的数据库出发丨TiDB Hackathon 选手访谈

PingCAP

TiDB

数据培训机构的学习费用是多少

小谷哥

PriorityQueue源码-成员变量解析

知识浅谈

Priority Queue 10月月更

深度解析:智能合约DAPP(bsc)币安链系统项目开发解决方案

I8O28578624

全网首发“Java面试考点大全”,25+专题梳理:JVM+多线程+Spring全家桶+MySQL+Redis等

Geek_0c76c3

Java 数据库 开源 程序员 开发

web前端开发培训学习后的就业方向

小谷哥

资源成本降低80%!Serverless云函数的弹性架构实践

极客天地

自制操作系统系列(三):加载其他文件执行

操作系统

使用Mask R-CNN模型实现人体关键节点标注

华为云开发者联盟

人工智能 华为云 mask 企业号十月 PK 榜

阿里内部最新发布的并发图册+JDK源码速成笔记,终于解脱束缚了

Geek_0c76c3

Java 源码 程序员 JVM 开发

2022年最新【Java经典面试800题】面试必备,查漏补缺;多线程+spring+JVM调优+分布式+redis+算法

Geek_0c76c3

Java 开源 程序员 架构 面试

C++:后现代的系统编程语言_语言 & 开发_刘清_InfoQ精选文章