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

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • opencv学习笔记之对灰度图像遍历的三种方法

    opencv学习笔记之对灰度图像遍历的三种方法灰度图像遍历的三种方法通过指针访问 通过迭代器访问 动态地址计算,通过at()函数实现、实现代码:#include#includeusingnamespacecv;usingnamespacestd;intmain(){ MatImg=imread(“1.jpg”,0); if(!Img.data){cout<

  • spring的事件监听应用场景_java监听器的原理与实现

    spring的事件监听应用场景_java监听器的原理与实现前言Spring从3.x开始支持事件机制。在Spring的事件机制中,我们可以令一个事件类继承ApplicationEvent类,然后将实现了ApplicationListener

  • KaOS Linux放出最新版ISO镜像喜迎五周岁

    KaOS Linux放出最新版ISO镜像喜迎五周岁

  • python unicode编码转换utf-8编码_不成问题的问题人物解析

    python unicode编码转换utf-8编码_不成问题的问题人物解析Unicode也叫万国码、单一码,是计算机科学领域里的一项业界标准,包括字符集、编码方案等。对于世界上所有的语言文字再unicode中都可以查看到。【汉】字的编码解释官网https://www.unicode.org/cgi-bin/GetUnihanData.pl?codepoint=6C49unicode编码就是为了统一世界上的编码,有一个统一的规范。但是它还存在一些问题。Unicode的问题需要注意的是,Unicode只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存

  • JAVA标识符命名规则及命名规范[通俗易懂]

    JAVA标识符命名规则及命名规范[通俗易懂]文章目录一、标识符可以标识什么二、标识符是什么三、标识符命名规则一、标识符可以标识什么标识符可以标识类名、方法名、变量名、接口名、常量名等。二、标识符是什么凡是程序员自己有权利命名单词的叫做标识符。但是main虽然是标识符,但是程序员不能修改。三、标识符命名规则命名规则属于语法机制,必须遵守,不遵守命名规则标识符不符合语法,编译器会报错。规则1:标识符只能有数字、字母(包括中文)、下划线、美元符号$组成。规则2:不能以数字开头。规则3:java关键字和保留字不能做为标识符。规则4:标

  • 数据库的左右连接和内连接_数据库各种连接的区别

    数据库的左右连接和内连接_数据库各种连接的区别原英文文章链接:https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins准备表A:–auto-generateddefinitionCREATETABLEtable_a(PKINT(10)NOTNULLPRIMARYKEY,Va…

发表回复

您的电子邮箱地址不会被公开。

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