现代程序设计 homework-07

本次作业要求为阅读C++11的新特性并写博客分享.

在这次作业之前,我对C/C++语言标准的印象只停留在C89 C99什么的...对于C99较C89的改进地方,我觉得很方便的地方也许只有说在C99中,允许程序猿在for语句的初始化部分定义一个或多个变量,这些变量的作用于仅限于本for语句所控制的循环体内,于是我们终于可以不必在循环开始前定义长长的一坨int i,int j,int abcdefg了...完全可以像下面这样

1 for(int i=0;i<n;i++)
2 {
3     do something naive;
4 }

而对于C++的语言标准,其实我并不是很了解的.而且现在的我越来越多的在使用C#,如果希望写的代码更加简洁一点可能使用的也是类C的C++.C++是一门伟大的语言,但是总感觉MFC似乎将C++拉低了一个层次.对于我这种低水平的coder来说,在做UI界面的时候,如果现在依旧停留在MFC那种一坨变量一坨指针一坨大写字母+下划线的命名方式,那真的是很蛋疼的感觉.不过据说微软已经放弃MFC,幸好现在有Winform,WPF,他们确实很简单...

 

以上都是题外话,这次我阅读了许多关于C++11标准的技术分享博客(维基的英文看的比较头疼..中文翻译的又实在是太差了..)

阅读文章/博客列表:

http://www.cnblogs.com/zhuyp1015/category/370450.html

http://blog.csdn.net/gzlaiyonghao/article/details/6564162

http://www.csdn.net/article/2012-05-15/2805585

http://en.wikipedia.org/wiki/C%2B%2B11

http://blog.jobbole.com/tag/c11/

发现C++11向C#,向脚本方向发展的洪流似乎是不可逆转了...确实出现了很多新颖并且有一定使用价值的新特性,但就针对我目前的水平来说,可能并不会对我产生实质性的大的改善.

 

一、关于auto关键字

C++11标准废除了旧的C++98标准中auto自动变量类型的意思,改成了自动类型推导的意思.

并且C++11也提供了从对象或表达式中“俘获”类型的机制,新的操作符decltype可以从一个表达式中"俘获"其结果的类型并"返回".

这个特性非常nice啊,特别像C#里面object 和 as的用法啊

比如我们来一段C#代码

1 Object x;
2 string xx=x as string;

那么我们搞成在C++里面是不是就可以这样

1 string x="hehe";
2 auto xx=x;
3 typedef decltype (xx) newType;
4 newType xxx;

这个样子看的话貌似博客园对C++11的支持还是不够好啊...

 

我对语言特性不是那么敏感,所以也提不出高端大气的问题,针对auto关键字我的问题是,这个特性究竟用在哪些确切的地方可以真正的让代码更加简洁?比如说C#中,我是用as这个关键字,那么可以在排序的时候实现接口的时候,就像上面那样将string类型提取出来...

 

二、统一的初始化语法

这篇博文http://blog.csdn.net/gzlaiyonghao/article/details/6564162这样提到了C++的至少四种初始化形式:

C++ 最少有 4 种不同的初始化形式,如括号内初始化,见:

1 std::string s("hello");
2 int m=int(); //default initialization

还有等号形式的:

1 std::string s="hello";
2 int x=5;

对于 POD 集合,又可以用大括号:

1 int arr[4]={0,1,2,3};
2 struct tm today={0};

最后还有构造函数的成员初始化:

1 struct S {
2  int x;
3  S(): x(0) {} };

这么多初始化形式,不仅菜鸟会搞得很头大,高手也吃不消。更惨的是 C++03 中居然不能初始化 POD 数组的类成员,也不能在使用 new[] 的时候初始 POD 数组,操蛋啊!C++11 就用大括号一统天下了:

 1 class C
 2 {
 3 int a;
 4 int b;
 5 public:
 6  C(int i, int j);
 7 };
 8 C c {0,0}; //C++11 only. 相当于 C c(0,0);
 9 int* a = new int[3] { 1, 2, 0 }; /C++11 only
10 class X {
11   int a[4];
12 public:
13   X() : a{1,2,3,4} {} //C++11, 初始化数组成员
14 };

还有一大好事就是对于容器来说,终于可以摆脱 push_back() 调用了,C++11中可以直观地初始化容器了:

1 // C++11 container initializer
2 vector vs<string>={ "first", "second", "third"};
3 map singers =
4   { {"Lady Gaga", "+1 (212) 555-7890"},
5     {"Beyonce Knowles", "+1 (212) 555-0987"}};

而类中的数据成员初始化也得到了支持:

1 class C
2 {
3  int a=7; //C++11 only
4 public:
5  C();
6 };

 

按照博主的观点,这个特性的确是很赞啊...不过到目前为止,对于初始化形式我只使用过等号和大括号形式,甚至对于构造函数的成员初始化都不是很经常用..(貌似C#用不到?)..现在的C++11将这些初始化形式统一为大括号,对于代码的整洁性方面确实有很大的提高,并且可以方便像我这样的菜鸟,不必对于不同形式的初始化方式而搞的云里雾里.对于容器的简洁操作,不必使用push_back(),确实是很方便啊!记得在切OJ题目的时候,有时候用到vector的时候初始化一直是一件很麻烦的事情,现在有了这个新特性,妈妈再也不用担心我的学习了..

 

三、新的关键字nullptr

nullptr是空指针常量,用来特带高风险的NULL宏和0字面常量.

原博文中这样提到

1 void f(int); //#1
2 void f(char *);//#2
3 //C++03
4 f(0); //调用的是哪个 f?
5 //C++11
6 f(nullptr) //毫无疑问,调用的是 #2

所有跟指针有关的地方都可以用nullptr,包括函数指针和成员指针

1 const char *pc=str.c_str(); //data pointers
2 if (pc!=nullptr)
3   cout<<pc<<endl;
4 int (A::*pmf)()=nullptr; //指向成员函数的指针
5 void (*pmf)()=nullptr; //指向函数的指针

这个特性也确实能够使我的编码更加规范,因为有的时候我确实就是NULL这个东西混用的...不过其实对于NULL和nullptr还有0字面常量,我并没有明确的定义,所以我在这里提出这样一个很基础的问题:NULL,nullptr以及0字面常量,究竟是如何定义的?

 

四、C++11标准库(线程库和新的模版算法)

我是读了博客之后才知道,C++11最新提供了thread类,并且可以用async()函数执行异步,由于平时用C#,线程类封装的很好,所以有一个疑问在这里:在C++11之前,程序猿们是如何利用C++实现多线程操作的?(...我竟然没有用C++实现过多线程..太罪过了..)

对于新的模版算法,C++11提供了all_of(),any_of(),none_of()...

这完全就是逻辑推理好么...

看起来确实很方便啊..这样程序猿们就不必扫描整个容器采用find操作去判断这些条件了.

像这篇博客中讲到的

1 #include <algorithm>
2 //C++11 code
3 //are all of the elements positive?
4 all_of(first, first+n, ispositive()); //false
5 //is there at least one positive element?
6 any_of(first, first+n, ispositive());//true
7 // are none of the elements positive?
8 none_of(first, first+n, ispositive()); //false

确实非常非常方便

原文还提到了copy_n()这个方法,不过这个操作和memcpy()操作..不是差不多么...

还有iota()算法,用来创建递增序列

例子像这样,

1 #include <numeric>
2 int a[5]={0};
3 char c[3]={0};
4 iota(a, a+5, 10); //changes a to {10,11,12,13,14}
5 iota(c, c+3, 'a'); //{'a','b','c'}

真心想给这个特性click zan啊...有的时候初始化一大坨东西的时候,比如字母表啊什么的一坨循环.现在有了这个iota()算法,完全可以只用一行简短的代码来实现了...

那么就在这里再提一个问题吧:对于C++11的标准库,还有哪些可以给我们带来实质性的方便的特性么?

 

五、Lambda表达式、右值引用、正则表达式

之所以把三个这么重要的特性放到一起放到最后来写,是因为囿于我的能力所限,在平时使用C++的时候并没有遇到过这些问题,而脚本语言什么的我也没有过多的接触,所以对于lambda表达式和正则文法没有什么太多的概念,右值引用貌似是很酷炫的特性,不过对于交换变量这种操作...我已经习惯了那三行代码,而且平时对内存管理什么的也不是很注重,所以可能无法理解右值引用,move操作带来的安全性的提升...

所以希望可以解决这样一个问题:这三大特性,究竟该如何应用到我们对C++的实际使用中?

 

六、总结

C++11出现了许多令人欣喜的新特性,我只针对我比较感兴趣或者说能够切实用到的特性简单的说明了一下,对于很重要的但是我暂时无法驾驭的新特性,我提出了我的问题.

以下是我提出的问题:

1.针对auto关键字我的问题是,这个特性究竟用在哪些确切的地方可以真正的让代码更加简洁?比如说C#中,我是用as这个关键字,那么可以在排序的时候实现接口的时候,就像上面那样将string类型提取出来...

2.NULL,nullptr以及0字面常量,究竟是如何定义的?

3.对于C++11的标准库,还有哪些可以给我们带来实质性的方便的特性么?

4.这三大特性(lambda表达式,右值引用,正则表达式),究竟该如何应用到我们对C++的实际使用中?

5.也是一个比较大的问题,如何兼顾掌握新技术与巩固旧知识之间的关系?(例如我现在对于C++11以前的标准还没有掌握好,而现在又出现了新的C++11标准)

posted @ 2013-11-10 22:34  VeryBigMan  阅读(429)  评论(1编辑  收藏  举报