现代C ++!=(大多数)新标准



术语“现代C ++”通常用作“使用新C ++标准的代码”表达的同义词。 在这里,“新”可以表示从C ++ 11到C ++ 17的任何东西,甚至可以是C ++ 20中已经可用的东西。 我认为现代C ++的功能更多,不仅限于添加-std = c ++ 17标志。

现代是什么意思?


如果我们在网上搜索“现代”一词的含义,则其中第一个是从Merriam-Webster词典中找到一个定义。 这是与C ++相关的两个部分:

[...]

2:涉及最新的技术,方法或思想:(最新的)现代交流方法

3大写:一种语言的当前或最近发展时期,与之相关或具有其特征-现代英语

[...]

技术,方法和思想不仅涉及语言的新功能。 这些新功能通常支持或包括新技术,但是其中许多已经存在了一段时间。 至于语言发展的特征,它们取决于我们如何使用语言。 这是指我们如何结合新旧功能,而不仅仅是一个可用的C ++程序或标准库中包含的程序。

有人可能会说,自C ++ 98以来存在的功能不是现代C ++的一部分,因为它们已经存在太久了。 但是,必须记住,社区中最活跃的谈论或撰写“现代C ++”的人通常是先锋。 大多数人都使用,研究甚至教授90年代的旧式“带类的C”,这使许多在C中没有使用的方法成为现代C ++的一部分。

新功能之外


我认为C ++ 98中的哪个可用属于“现代C ++”类别? 以下是一些重要功能和想法的部分列表:

区域情报研究所


RAII代表“获取资源就是初始化”,或者“获取责任就是初始化”。 尽管名称集中在“初始化”上,但这里的关键部分实际上是析构函数。 确定性释放资源是C ++与其他大多数语言不同的主要特征之一。 对于许多人来说,这是最重要的特征。

RAII可用于可靠地管理许多事情,例如内存(例如std :: vector,std :: string ),文件描述符( std :: fstream ),网络连接,互斥锁,数据库连接以及与资源关系密切。 如果需要可靠的方法来执行某些操作,然后在退出某个范围或销毁对象时取消该操作,则需要RAII。

我看到了很多代码,其中功能结束时的手动清理变成了噩梦。 在例外情况下,不会进行此类清洁,因此在这种情况下, 您需要RAII 。 即使您不使用异常, 提前退出函数也可以显着改善您的代码,但前提是您不需要清理它。

尽管从一开始就可以使用RAII技术,但它绝对是现代C ++的一部分。

强大的打字


强类型化的想法最近很流行。 过去,所有标识符,大小,邮政编码,价格等都是通过int或double或其他算术类型表示的。 它们是兼​​容的,彼此之间完全不相关,这完全是偶然的,它们是同一类型,这是错误的根源,但是我该怎么办? 至少编译器不会默默地将数字和数组转换为字符串

实际上,事实证明,编译器为我们提供的C ++类型系统和零成本*抽象可以做很多事情。 只需为标识符,邮政编码,大小(不,没有typedef,谢谢)等创建不同的类型。 如果您有兴趣,请查看BjörnFahllerJonathan BoccaraJonathanMüller的讲座之一。

*(即使抽象成本不为零, 也要在放弃之前证明它是不可接受的

除了最近的一些新增功能之外,<algorithm>从一开始就位于标准库中。 但是,如果您看一下代码,事实证明人们经常喜欢手动编写循环。 原因包括从不知道可用的标准算法到认为“模板太慢”(相比之下,通常都没有解释)。

编写编译阶段


从C ++ 98开始,就开始使用诸如使用模板进行元编程之类的事情。 在编译时执行的逻辑可以大大降低运行时的复杂度。 过去,使用起来很不方便。 模板的语法在复杂性方面与最新标准中的功能有所不同。 这就像我们必须学习的另一种语言。 但是,诸如标签分派或特征之类的东西使用和编写起来并不太复杂。

是的,标准库中的大多数特征都是随着C ++ 11的出现而出现的,但是根据您的需求编写它们并不是很困难,并且一些最常见的特征是在C ++ 11之前的Boost中。 我认为使用编译阶段逻辑是现代C ++的一部分,因为它将C ++与无处不在的“带有类的C”分开。

结论


现代C ++与新标准无关,而与我们编写程序的方式有关。 首先,可以用或多或少的现代风格来编写C ++ 98。 其次,“具有类和基于范围的for循环的C”尚未成为现代C ++。 语言和库的新功能帮助我们以现代C ++的方式编写代码,但它们并未使我们的代码成为现代C ++。

Source: https://habr.com/ru/post/zh-CN429780/


All Articles