您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > C/C++/C#

C++这七大特性

时间:2019-08-26 16:00:19  来源:  作者:

来源:Pexels

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

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

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

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

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

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

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

 

1. 关键字auto

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

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

 

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

 

 

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

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

 

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

 

 

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

 

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

 

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

 

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

 

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

 

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

 

 

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

 

2. 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.

 

3. 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
}

 

4. 在编译时使用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.

 

5. Tuples元组

 

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

 

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

 

 

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

 

6. 类模板参数推导

 

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

std::pair<std::string,int> user = {"M", 25}; // previous
std::pair user = {"M", 25}; // C++17

 

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

// previous
std::tuple<std::string, std::string, int> user ("M","Chy", 25);
// deduction in action! 
std::tuple user2("M", "Chy", 25);

 

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

 

7. 智能指针

 

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

 

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

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



Tags:C++   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
一、编程语言1.根据熟悉的语言,谈谈两种语言的区别?主要浅谈下C/C++和PHP语言的区别:1)PHP弱类型语言,一种脚本语言,对数据的类型不要求过多,较多的应用于Web应用开发,现在好多互...【详细内容】
2021-12-15  Tags: C++  点击:(17)  评论:(0)  加入收藏
函数调用约定(Calling Convention),是一个重要的基础概念,用来规定调用者和被调用者是如何传递参数的,既调用者如何将参数按照什么样的规范传递给被调用者。在参数传递中,有两个很...【详细内容】
2021-11-30  Tags: C++  点击:(19)  评论:(0)  加入收藏
一、为什么需要使用内存池在C/C++中我们通常使用malloc,free或new,delete来动态分配内存。一方面,因为这些函数涉及到了系统调用,所以频繁的调用必然会导致程序性能的损耗;另一...【详细内容】
2021-11-17  Tags: C++  点击:(38)  评论:(0)  加入收藏
C++编程中,你是否有为 我到底该写个struct还是class 而苦恼过?如果你到现在还不知道该如何选择,那么请求继续阅读,下文或许能给你些建议。问题的产生C++语言继承了 C语言的 stru...【详细内容】
2021-10-18  Tags: C++  点击:(63)  评论:(0)  加入收藏
C++在C的面向过程概念的基础上提供了面向对象和模板(泛型编程)的语法功能。下面以一个简单实例(动态数组的简单封装,包括下标的值可以是任意正数值,并提供边界检查)来说明C++是如...【详细内容】
2021-10-18  Tags: C++  点击:(50)  评论:(0)  加入收藏
0 前言Hello,大家好,欢迎来到『自由技艺』的 C++ 系列专题。代码重用,尽可能避免冗余代码是程序员的一项必备技能,今天就来给大家介绍其中一种:函数装饰器。在设计模式中,与它对应...【详细内容】
2021-09-28  Tags: C++  点击:(75)  评论:(0)  加入收藏
今天我们就来聊一聊 C++ 中的异常机制吧。在学校期间,我们很少会用得上异常机制。然而,工作之后,很多时候却不得不引入异常机制。因为一般情况下,使用函数的返回值来确定函数的...【详细内容】
2021-09-26  Tags: C++  点击:(182)  评论:(0)  加入收藏
一、内存泄漏(memory leak)内存泄漏(memory leak)是指由于疏忽或错误造成了程序未能释放掉不再使用的内存的情况。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存...【详细内容】
2021-09-03  Tags: C++  点击:(105)  评论:(0)  加入收藏
stack容器#include <iostream>using namespace std;#include <stack>//容器头文件void test(){stack<int>p;p.push(100);p.push(1000);p.push(100);while(!p.empty()){cout<...【详细内容】
2021-08-17  Tags: C++  点击:(81)  评论:(0)  加入收藏
stl 常用遍历算法(for_each transform)示例代码(结论在结尾!!!!)#include<iostream>using namespace std;#include"vector"#include"map"#include"string"#include"list"#in...【详细内容】
2021-08-13  Tags: C++  点击:(89)  评论:(0)  加入收藏
▌简易百科推荐
一、简介很多时候我们都需要用到一些验证的方法,有时候需要用正则表达式校验数据时,往往需要到网上找很久,结果找到的还不是很符合自己想要的。所以我把自己整理的校验帮助类分...【详细内容】
2021-12-27  中年农码工    Tags:C#   点击:(2)  评论:(0)  加入收藏
引言在学习C语言或者其他编程语言的时候,我们编写的一个程序代码,基本都是在屏幕上打印出 hello world ,开始步入编程世(深)界(坑)的。C 语言版本的 hello world 代码:#include <std...【详细内容】
2021-12-21  一起学嵌入式    Tags:C 语言   点击:(11)  评论:(0)  加入收藏
读取SQLite数据库,就是读取一个路径\\192.168.100.**\position\db.sqlite下的文件<startup useLegacyV2RuntimeActivationPolicy="true"> <supportedRuntime version="v4.0"/...【详细内容】
2021-12-16  今朝我的奋斗    Tags:c#   点击:(21)  评论:(0)  加入收藏
什么是shellshell是c语言编写的程序,它在用户和操作系统之间架起了一座桥梁,用户可以通过这个桥梁访问操作系统内核服务。 它既是一种命令语言,同时也是一种程序设计语言,你可以...【详细内容】
2021-12-16  梦回故里归来    Tags:shell脚本   点击:(18)  评论:(0)  加入收藏
一、编程语言1.根据熟悉的语言,谈谈两种语言的区别?主要浅谈下C/C++和PHP语言的区别:1)PHP弱类型语言,一种脚本语言,对数据的类型不要求过多,较多的应用于Web应用开发,现在好多互...【详细内容】
2021-12-15  linux上的码农    Tags:c/c++   点击:(17)  评论:(0)  加入收藏
1.字符串数组+初始化char s1[]="array"; //字符数组char s2[6]="array"; //数组长度=字符串长度+1,因为字符串末尾会自动添&lsquo;\0&lsquo;printf("%s,%c\n",s1,s2[2]);...【详细内容】
2021-12-08  灯-灯灯    Tags:C语言   点击:(47)  评论:(0)  加入收藏
函数调用约定(Calling Convention),是一个重要的基础概念,用来规定调用者和被调用者是如何传递参数的,既调用者如何将参数按照什么样的规范传递给被调用者。在参数传递中,有两个很...【详细内容】
2021-11-30  小智雅汇    Tags:函数   点击:(19)  评论:(0)  加入收藏
一、问题提出问题:把m个苹果放入n个盘子中,允许有的盘子为空,共有多少种方法?注:5,1,1和1 5 1属同一种方法m,n均小于10二、算法分析设f(m,n) 为m个苹果,n个盘子的放法数目,则先对...【详细内容】
2021-11-17  C语言编程    Tags:C语言   点击:(49)  评论:(0)  加入收藏
一、为什么需要使用内存池在C/C++中我们通常使用malloc,free或new,delete来动态分配内存。一方面,因为这些函数涉及到了系统调用,所以频繁的调用必然会导致程序性能的损耗;另一...【详细内容】
2021-11-17  深度Linux    Tags:C++   点击:(38)  评论:(0)  加入收藏
OpenCV(Open Source Computer Vision Library)是一个(开源免费)发行的跨平台计算机视觉库,可以运行在Linux、Windows、Android、ios等操作系统上,它轻量级而且高效---由一系列...【详细内容】
2021-11-11  zls315    Tags:C#   点击:(50)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条