C++Annoatation 02: More extensions to C , Some features of C++11

C++Annoatation 02: More extensions to C , Some features of C++11

More extensions to C , Some features of C++11

对于稍微有些C++的同学,大概都知道C++和C的一些主要区别,大的区别就是一个是面向对象,一个是面向过程,这就涉及到对象; 同时,还有命名空间的引入,防止变量名冲突; 还有struct支持成员函数等。 我就继续注释一些更需要注意的一些不同,一些是C++11中的东西。
 
引用
可以通过引用修改它引的对象,但是不能改变它本身。这么听来,就像是常量指针, 另外,引用也让代码更加自然,不像c里边会出现一堆的&来表示传址调用。
int a
=
1;


int
&r
=a;


int
*
const rr
= a;
// int*const 和 int&是同一个东西,引用只是一个语法糖。

 
使用引用时,有几点需要记住:
引用定义时必须初始化! 其实看上面的程序例子就知道, const的东西都必须初始化
不要在函数中返回局部变量的引用
函数中是否使用引用的场合
引用,可以当做函数参数传入,这样就可能会修改所引用对象。指针也能达到这样的目的,这样多多少少会造成一些困惑,我们可以依从一些原则:
 
形参是内建类型(int double char等),且我们不需要改变实参值,直接传值调用
若形参时内建类型,且我们需要修改它,那就通过指针*调用
 
形参类型是,结构体等,我们不需要改变它的成员变量,采用 const & 调用
若形参类型是类等,需要改变,采用引用&调用
 
使用引用调用,能够避免构造函数的调用,节省开支。
 
另外,需要实现链式操作的,返回值选择引用类型,也能避免构造函数的调用。经典例子就是 “cout”
右值引用 (对C++11不是很熟悉,会有一些理解上的错误,请指正)
C++11中多了个右值引用。 主要是因为临时变量(右值)不能很好的同 const& 很好的区分开来,因此C++11多了个右值引用&&。
举例说明下:
int intVa()

{


return
5;

}


int
& a
= intVal();
// 错误! 引用临时变量


int
const
& a
= intVal();
// 正确,引用不变临时变量


int
* a
=
&intVal();
// 错误! intVal()不是左值

 
我们继续看:
void receive(
int
& value){
++value; cout
<<“L
value parameter\n”;} // 左值引用版本


void receive(
int
&& value){
++value; cout
<<
“R-value parameter\n”;} // 右值引用版本


void receive(
int
const
& value)
{
++value;
cout
<<
“L-value const parameter\n”;}
// ++value不能有,否则编译错误。这算是右值引用和const&的区别。

 
如此调用:
int main()

{

receive(
18);
// R-value 19


int v
=
5;


int
const
& cri
= v;

receive(cri);
// L-value const

receive(v);
// L-value 6

receive(intVal());
// R-value 6

}

 
若我们把 void receive(int& value)删除,则receive(v) 返回 L-value const parameter。 函数重载的右值引用版本,仅在匿名变量传入时激发。
另外,右值引用版本函数中,可以对value进行操作,可以看出,右值引用 用于获取 匿名临时变量 的 操纵权,而 int const& 版本的却不行。
注意下:
若引入另外个重载版本 void(int value), 那么将发生错误,因为该例中,匿名变量也可以解析成 int 型,导致重载冲突。
 
另外,右值引用的进阶应用是 是 移动语义 move semantics 和 完美转发 perfect forwarding 的基础。移动语义我暂时还不懂啥,以后再讲述。
强类型-枚举类
C++中,枚举类型其实就是int,不同枚举类型可以通过static_cast<int> 来进行比较操作;另外,不同枚举类型的内部值不能相同,因为C++中枚举类型的作用范围不被枚举名所限,而是受作用域限制。
C++11中,引入了 enum class ,来解决上述问题。
enum
class CharEnum
:
unsigned
char
// 默认是int,可以通过这个“:”符号改变

{

NOT_OK,
// 默认 0

OK
// 自增1

};

 
使用时,要加入枚举类名与作用域符,即 CharEnum::OK.
前向声明如下
enum Enum1;
// Illegal: no size available


enum Enum2
:
unsigned
int;
// Legal in C++11: explicitly declared type

enum
class Enum3;
// Legal in C++11: default int type is used


enum
class Enum4
:
char;
// Legal in C++11: explicitly declared type

初始化列表
c语言中,可以用大括号包含一个初始化列表来初始化数组、结构体。C++11把这个概念继续扩展了,引入了

initializer_list<Type> 这个模本类,可以扩展初始化类,同时也能对初始化列表进行个性化操作。 使用前,要包含头文件 <initializer_list> 。同时,可以将初始化列表当做函数形参传入。
void values(initializer_list
<
int
> iniValues)

{

cout
<<
“Initializer list having “
<< iniValues.size()
<<
“values\n”;


for

(

initializer_list
<
int
>
:
:const_iterator begin
= iniValues.begin();

begin
!= iniValues.end();


++begin

)

cout
<<
“Value: “
<<
*begin
<<
‘\n’;

}

 
这个知识点Mark下,以后继续深入了解,记得在 boost 中好像也有类似的东西。
auto 和 decltype 这个我觉得,最好了
由于C++的声明可能会非常复杂难懂,C++11将曾经的auto关键字改造,使其能够自动解析类型,不错,基于boost的改进。
auto 和 decltype 功能异常强大,不过个人认为,还是要把模板知识搞透了再深入使用这个关键字比较好,基础神马的,最重要的了。
 
int (*fun())[10], 表示 fun是个函数,返回一个指向int数组[10]的指针。这样不好理解,用上auto后,一切这么自然
auto func() -> int(*)[10];
另外,比如 vector<int>::const_iterator ci = v.begin(); 可以改写成 auto ci = v.begin(); 例子很多,相信auto的使用,会让C++更加受欢迎。
 
类型定义和 ‘using’ 声明
 
比如 unsigned long int compute(double, double), 这个函数指针的声明,使用typedef可以变成这样:
typedef unsigned long int(*pfun)(double, double);
但是,我们声明时 pfun f; 时,掩盖了Pfun实际上是一个指针的事实,必须看typedef定义才知道。关于这点,我很诟病,导致我函数指针一直没学好。C++11中将这点进行了升华,采用using 关键字:
using pfun
=
unsigned
long
int(
double,
double);

或者和
auto配合:


using pfun
=
auto (
double,
double)

>
unsigned
long
int;

for循环的范围操作
传统C/C++ 的for采用标准的 for(init;cong;next)语句,这对遍历的使用,不那么的便捷,很多语言都提供了范围操作符,在STL的算法库也包含了for_each方法,但是还是不够便捷。C++11中引入了for的范围操作版本:
int array[100];
for (auto &element:array){…}
这里,推荐使用auto,避免思想负担在解析类型上。 同时,element是变量名,表示array中每次遍历的元素。 引用操作符非常重要,若是要修改元素或array是类类型,则用引用; 若是类类型,但不改变,用const&; 普通的内建类型且不改变,可以不用&。
有了这个范围操作,C++算是一大进步呀。
原始字符串
传统C/C++使用””包含字符串,用\来做逃脱而字符。这样,我们会在代码中看到一堆的 \\\\\\ 实在很影响阅读。现在很多语言都支持正则表达式了,而正则中最多也正是\\这样的符号,让C++来使用,my god! 。我觉得C++可能借鉴了python的R字符串,和perl的定界符规则,引出自己的原始字符串,在原始字符串中,不存在逃脱语义。写法如下:
R”(string)” 写法一

R"delimiter(string)delimiter" 写法二
更细致的阐述,打算放在正则表达式时讨论。
 
新增类型说明符
ob0101: 表示二进制的5
F : 说明是一个浮点型常量 3F
L : 前缀使用说明字符串中字符是wchar_t, 后缀使用说明是一个 long
p :十六进制数*(2^p), 即左移p。
 
增加对 Unicode 的支持
字符串:


char utf_8[]
= u8
“This is UTF-8 encoded.”;

char16_t utf16[]
= u
“This is UTF-16 encoded.”;

char32_t utf32[]
= U
“This is UTF-32 encoded.”;

 
对unicode常量,使用\u逃脱,加上一个十六进制量


char utf_8[]
= u8
“\u2018”;

char16_t utf16[]
= u
“\u2018”;

char32_t utf32[]
= U
“\u2018”;

同样,表达式可以使用原始字符串

感慨:C++复杂太多了,多了太多东西了,每个知识点都是一大章的东西,看来,路漫漫呀!
 

转载于:https://www.cnblogs.com/IntellX/archive/2013/05/21/3090432.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/110125.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • linux查看crontab状态_crontab -e

    linux查看crontab状态_crontab -elinux下定时执行任务的方法在LINUX中,周期执行的任务一般由cron这个守护进程来处理[ps-ef|grepcron]。cron读取一个或多个配置文件,这些配置文件中包含了命令行及其调用时间。cron的配置文件称为“crontab”,是“crontable”的简写。一、cron在3个地方查找配置文件:1、/var/spool/cron/这个目录下存放的是每个用户包括root的cron…

    2022年8月24日
    7
  • 以《简单易懂》的语言带你搞懂有监督学习算法【附Python代码详解】机器学习系列之KNN篇[通俗易懂]

    以《简单易懂》的语言带你搞懂有监督学习算法【附Python代码详解】机器学习系列之KNN篇[通俗易懂]机器学习系列往期回顾❤️开始学习机器学习之前你必须要了解的知识有哪些?机器学习系列入门篇在上篇文章中,我们介绍了机器学习的一些理论知识,包括什么是监督学习、无监督学习、过拟合欠拟合等等,那在本篇文章中,我们会以KNN来正式介绍什么是有监督学习,让大家在了解KNN的同时完全掌握什么是有监督学习,以帮助大家更好的理解机器学习。注:本篇文章非常详细,附带简单易懂的文字说明和实现代码,欢迎收藏后慢慢阅读。监督学习算法本文主要介绍的有监督学习算法是KNN,后续会接着介绍决策树、线性回归等算法。

    2022年5月28日
    40
  • 列式数据库_开源列式数据库

    列式数据库_开源列式数据库列式数据库是相对于行式存储的数据库,Oracle、MySQL、SQLServer等数据库都是采用的行式存储(Row-based),而列式数据库是将数据按照列存储到数据库中,这样做的好处是可以大量降低系统的I/O,适合于分布式文件系统,不足在于功能相对有限。典型产品:HBase等。…

    2022年10月22日
    0
  • 腾讯云免费SSL证书配置

    腾讯云免费SSL证书配置基于ngnix的https配置1.证书上传1)申请证书请参照官方文档,然后把已经颁发下来的证书下载下来。2)解压文件,然后把ngnix文件夹下的1_xxx.com_bundle.crt和2_xxx.com.key上传到服务器的nginx配置文件目录(上传到同一目录),如:/usr/loc…

    2022年9月3日
    2
  • ubuntu18安装yarn、安装vue

    ubuntu18安装yarn、安装vue操作系统为ubuntu18第一步:换源sudopython-c"s=’mirrors.163.com’;importre;f=open(‘/etc/apt/sources.list’,’r+’);a=f.read();f.seek(0);f.truncate();f.write(re.sub(r'(deb|security)\.debian\.org’,s,a));f.clo…

    2022年5月25日
    35
  • Python的pywifi模块

    Python的pywifi模块想蹭❤️小姐姐的热点❤️被拒后,我用❤️Python来暴力激活成功教程了WiFi的密码❤️文章目录想蹭❤️小姐姐的热点❤️被拒后,我用❤️Python来暴力激活成功教程了WiFi的密码❤️一、起因背景二、需求分析三、代码实现1、生成密码本2、利用密码本进行自动化的测试3、结果展示四、后续总结一、起因背景这天博主和曾经的一个小姐姐同学凑巧同时坐在了同一辆长途客车上,恰谈之后才了解到原来这位小姐姐家里挺富裕的,居然,开通了无限的流量使用权限,博主心想,既然是老同学了,借用一下这个无限的流量应该是没什么问题吧,反正是

    2022年7月27日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号