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)


相关推荐

  • 概率(Probability)的定义和性质

    描述性定义:在相同的条件下,独立重复地做NNN次试验,当试验次数NNN很大时,如果事件AAA发生的频率fN(A)fN(A)f_N(A)稳定地在[0,1][0,1][0,1]内的某一个数值ppp,而且一般来说随着试验次数的增多,这种摆动的幅度会越来越小,则称数值ppp为事件AAA发生的概率,记为P(A)=pP(A)=pP(A)=p…

  • SQL 循环语句 while 介绍 实例

    WHILE设置重复执行SQL语句或语句块的条件。只要指定的条件为真,就重复执行语句。可以使用BREAK和CONTINUE关键字在循环内部控制WHILE循环中语句的执行。语法WHILE

    2021年12月27日
  • KindEditor富文本编辑器 items配置项 对照表「建议收藏」

    KindEditor富文本编辑器 items配置项 对照表「建议收藏」source:’HTML代码’, undo:’后退(Ctrl+Z)’, redo:’前进(Ctrl+Y)’, cut:’剪切(Ctrl+X)’, copy:’复制(Ctrl+C)’, paste:’粘贴(Ctrl+V)’, plainpaste:’粘贴为无格式文本’, wordpaste:’从Word粘贴’, selectall:

  • c#防止代码被反编译_C程序反编译

    c#防止代码被反编译_C程序反编译1.在编码过程中尽量使用private/internal关键词修饰class、方法和字段名称2.编码过程尽可能少地使用public修饰class、方法和字段名称3.避免使用反射和序列化,反序列化操作4.添加生成事件,调用Dotfuscator进行代码混淆if$(ConfigurationName)==Debug”C:/ProgramFiles(x86)/MicrosoftVisualStudio14.0/PreEmptiveSolutions/Dotfuscatora

  • navicate 15 激活码【注册码】

    navicate 15 激活码【注册码】,https://javaforall.cn/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

  • android之Random.nextInt(k)陷阱「建议收藏」

    android之Random.nextInt(k)陷阱「建议收藏」API:Returnsapseudo-randomuniformlydistributedintinthehalf-openrange[0,k). 意思就是说,nextInt的取值是0到k-1,不包括k。

发表回复

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

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