不知道C++这七大特性,绝对枉为圈中人

栏目: C++ · 发布时间: 5年前

内容简介:作为一种计算机语言,C++经历了许多发展变化。当然,这些改变并不是一蹴而就的。C++曾经缺乏活力与创新,因此很不受欢迎。但是在C++标准委员会决定加速发展这个语言之后,形势发生了改变。

作为一种计算机语言,C++经历了许多发展变化。

当然,这些改变并不是一蹴而就的。C++曾经缺乏活力与创新,因此很不受欢迎。

但是在C++标准委员会决定加速发展这个语言之后,形势发生了改变。

2011年起,C++一跃成为了具有活力、不断演进、广受喜爱的计算机语言。

最后,如果大家如果在自学遇到困难,想找一个C++的学习环境, 可以加入我们的C++学习圈,点击我加入吧 ,会节约很多时间,减少很多在学习中遇到的难题。

不知道C++这七大特性,绝对枉为圈中人

C++蜕变后也并没有简单多少,仍是最难的编程语言之一。但是,C++确实比之前更加人性化了。

本文要讲的是的C++的一些新特性(以有8年历史的C++11为例),相信每个 程序员 都会对这个话题感兴趣。

注:本文略过了一些高级特性。

  1. 关键字auto

当C++11第一次引入auto时,程序员们纷纷喜极而泣!

auto的意义是使C++编译器可以在编译时推导数据类型,这样就不用每次都要声明数据类型了。当数据类型为map>>时尤为便捷。

不知道C++这七大特性,绝对枉为圈中人

没有initializer,就无法声明数据类型(见第五行)。这是说得通的。第五行指令并没有让编译器推导数据类型。

起初,auto的功能比较有限。在之后新版本的C++中,auto的功能越来越强大。

不知道C++这七大特性,绝对枉为圈中人

第七行和第八行中使用了括号初始化 (bracketedinitialization),这也是C++11的新特性之一。

请注意使用auto时,编译器必须能够推导数据类型。

一个有趣的问题是:如果写下autoa = {1, 2, 3}会发生什么?这是个编译错误吗?是一个矢量吗?

不知道C++这七大特性,绝对枉为圈中人

实际上,C++11引入了std::initializer_list.如果声明auto,花括号初始化列表会被当做轻量级容器。

最终,正如前文所言,当数据结构复杂时,编译器类型推导很有帮助:

不知道C++这七大特性,绝对枉为圈中人

别忘了检查第25行!auto [v1,v2] = itr.second纯粹是C++17的新特性。这个特性叫做结构化绑定。在旧版本C++中,程序员需要单独获取每个变量。但是结构化绑定给这一过程带来了便利。此外,如果想获得数据使用引用(reference),只需要加上一个symbol--auto&[v1,v2] = itr.second.

  1. Lambda表达式

C++11引入了lambda表达式,这类似于JavaScript里的匿名函数。它们都是函数对象,没有名字,且基于简洁的语法在不同作用域上捕获变量。它们也可以被分配给变量。

如果需要在代码中进行一些小而快的操作,又不愿意为此单独写一个函数,那么Lambdas很有用。另一种常见用法是将lambdas作为比较函数。

不知道C++这七大特性,绝对枉为圈中人

以上例子可以说明很多问题。

首先,请注意花括号初始化是如何提升权重的。然后是通用的begin(),end() (这也是C++11的新增部分)。接着是作为数据比较器的lambda函数。lambda函数的参数被声明为auto(这是C++14的新增部分)。在C++14之前是不能对于函数参数使用auto 的。

正如现代C++的awesome库中定义的那样:

· []—不捕获任何对象。所以不能在lambda表达式内使用全局作用域的局部变量,只能使用参数。

· [=]— 按值捕获作用域中的局部对象(局部变量,参数)。只可使用不可修改。

· [&]—按引用捕获作用域中的局部对象(局部变量,参数)。可以被修改。例子如下。

· [this]—按值捕获this 指针。

· [a, &b]—按值捕获对象a ,按引用捕获对象b。

所以,如果想在lambda函数内部将数据转换为其他格式,可以利用作用域的优势来运用lambda.比如:

不知道C++这七大特性,绝对枉为圈中人

在上面这个例子中,如果在lambda表达式中按值捕获([factor])局部变量,则不能改变第五行的factor.原因很简单——没有权限。

最终,请注意示例中使用了val 作为引用 (reference). 这确保了lambda函数内部的任何变化都会改变vector.

不知道C++这七大特性,绝对枉为圈中人

学完现代C++后,她们乐开了花!(摄影:Ian Schneider 图源:Unsplash)

  1. if/switch内的初始化语句

C++17的这个特性十分讨喜:

不知道C++这七大特性,绝对枉为圈中人

很明显,现在可以同时在if/switch句块内进行变量初始化和条件检查。这有助于保持代码简洁精炼。通用形式为:

if( init-statement(x);condition(x)) {

// do some stuff here

} else {

// else has the scope of x

// do some other stuff

}

  1. 在编译时使用constexpr

constexpr 很棒!假如要评估一些表达式,且它的值一旦初始化就不会改变,那么可以预运算其值并将之作为宏。或者利用C++11提供的constexpr.

程序员倾向于尽量减少程序运行时间。所以,如果能让编译器进行一些操作并减小程序运行的压力,那么就可以缩短运行时间。

不知道C++这七大特性,绝对枉为圈中人

以上代码是constexpr的常见例子之一。既然声明斐波那契数列函数为constexpr, 那么编译器就可以在编译时预运算fib(20). 所以编译之后,可以用constlong long bigval = 2432902008176640000来替代const longlong bigval = fib(20).

请注意,传递参数是一个const 值。这是被声明为constexpr的函数的一个重点——传递参数应该是constexpr或const。否则这里的函数会和普通函数一样,也就是说编译时不进行预运算。

变量也可以是constexpr. 在这种情况下,这些变量在编译时必须可评估;否则会出现编译错误。

有趣的是,后来在C++17中引入了constexpr-if 和constexpr-lambda.

  1. Tuples元组

与pair非常类似, tuple是各种数据类型的固定大小值的集合。

不知道C++这七大特性,绝对枉为圈中人

有时,相比于tuple,使用 std::array更方便。array类似于带有C++标准库的功能的plain C阵列。这个数据结构是C++11新增的。

  1. 类模板参数推导

这个特性的名字还挺啰嗦。从C++17开始,标准类模板也可以进行模板参数推导。之前,模板参数推导只支持函数模板。结果就是:

std::pair user = {"M", 25}; // previous

std::pair user = {"M", 25}; // C++17

这种推导是“隐性的”。这对于tuple来说就更方便了。

// previous

std::tuple user ("M","Chy", 25);

// deduction in action!

std::tuple user2("M", "Chy", 25);

以上这一特性对不熟悉C++模板的人来说没有太大用处。

  1. 智能指针

指针有时很恐怖。由于C++语言为程序员提供了很大程度的自由,所以有时很容易搬起石头砸自己的脚。而且很多情况下,麻烦是由指针造成的。

幸运的是,C++11引入了智能指针,智能指针比普通指针便捷得多。它们通过适时释放内存来帮助程序员防止内存泄漏。它们还有助于代码达到异常安全等级。

C++为最新版本的计算机语言引入了许多全新的特性。如果你感兴趣,可以进行深入了解。

不知道C++这七大特性,绝对枉为圈中人


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Dynamic Programming

Dynamic Programming

Richard Bellman / Dover Publications / 2003-03-04 / USD 19.95

An introduction to the mathematical theory of multistage decision processes, this text takes a "functional equation" approach to the discovery of optimum policies. The text examines existence and uniq......一起来看看 《Dynamic Programming》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

在线进制转换器
在线进制转换器

各进制数互转换器

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换