C++11 中值得关注的几大变化(详解)
2012-11-14 13:51
513 查看
http://coolshell.cn/articles/5265.html
源文章来自前C++标准委员会的 Danny Kalev 的 The Biggest Changes inC++11 (and Why You Should Care),赖勇浩做了一个中文翻译在这里。所以,我就不翻译了,我在这里仅对文中提到的这些变化“追问为什么要引入这些变化”的一个探讨,只有知道为了什么,用在什么地方,我们才能真正学到这个知识。而以此你可以更深入地了解这些变化。所以,本文不是翻译。因为写得有些仓促,所以难免有问题,还请大家指正。
Lambda 表达式
Lambda表达式来源于函数式编程,说白就了就是在使用的地方定义函数,有的语言叫“闭包”,如果 lambda 函数没有传回值(例如 void ),其回返类型可被完全忽略。 定义在与 lambda 函数相同作用域的变量参考也可以被使用。这种的变量集合一般被称作 closure(闭包)。我在这里就不再讲这个事了。表达式的简单语法如下,那么,除了方便外,为什么一定要使用Lambda呢?它比传统的函数或是函数对象有什么好处呢?我个人所理解的是,这种函数之年以叫“闭包”,就是因为其限制了别人的访问,更私有。也可以认为他是一次性的方法。Lambda表达式应该是简洁的,极私有的,为了更易的代码和更方便的编程。
自动类型推导 auto
在这一节中,原文主要介绍了两个关键字 auto 和 deltype,示例如下:比如下面的代码的可读性就降低了。因为,我不知道ProcessData返回什么?int? bool? 还是对象?或是别的什么?这让你后面的程序不知道怎么做。
自动化推导 decltype
关于decltype是一个操作符,其可以评估括号内表达式的类型,其规则如下:
如果表达式e是一个变量,那么就是这个变量的类型。
如果表达式e是一个函数,那么就是这个函数返回值的类型。
如果不符合1和2,如果e是左值,类型为T,那么decltype(e)是T&;如果是右值,则是T。
原文给出的示例如下,我们可以看到,这个让的确我们的定义变量省了很多事。
auto 和 decltype 的差别和关系
Wikipedia 上是这么说的(关于decltype的规则见上)forwarding function 模板”,
统一的初始化语法
C/C++的初始化的方法比较,C++ 11 用大括号统一了这些初始化的方法。比如:POD的类型。
从这点可以看出,C/C++的初始化问题很奇怪,所以,在C++ 2011版中就做了统一。原文作者给出了如下的示例:
Delete 和 Default 函数
我们知道C++的编译器在你没有定义某些成员函数的时候会给你的类自动生成这些函数,比如,构造函数,拷贝构造,析构函数,赋值函数。有些时候,我们不想要这些函数,比如,构造函数,因为我们想做实现单例模式。传统的做法是将其声明成private类型。在新的C++中引入了两个指示符,delete意为告诉编译器不自动产生这个函数,default告诉编译器产生一个默认的。原文给出了下面两个例子:
1)让你的对象只能生成在栈内存上:
f(),将会引发编译期错误, 编译器不会自动将 double 形参转型为 int 再调用
f(),如果传入的参数是double,则会出现编译错误)
nullptr
C/C++的NULL宏是个被有很多潜在BUG的宏。因为有的库把其定义成整数0,有的定义成 (void*)0。在C的时代还好。但是在C++的时代,这就会引发很多问题。你可以上网看看。这是为什么需要nullptr的原因。
nullptr是强类型的。
所以在新版中请以 nullptr初始化指针。
委托构造
在以前的C++中,构造函数之间不能互相调用,所以,我们在写这些相似的构造函数里,我们会把相同的代码放到一个私有的成员函数中。右值引用和move语义
在老版的C++中,临时性变量(称为右值”R-values”,位于赋值操作符之右)经常用作交换两个变量。比如下面的示例中的tmp变量。示例中的那个函数需要传递两个string的引用,但是在交换的过程中产生了对象的构造,内存的分配还有对象的拷贝构造等等动作,成本比较高。举例而言,上面那个例子中,string类中保存了一个动态内存分存的char*指针,如果一个string对象发生拷贝构造(如:函数返回),string类里的char*内存只能通过创建一个新的临时对象,并把函数内的对象的内存copy到这个新的对象中,然后销毁临时对象及其内存。这是原来C++性能上重点被批评的事。
能过右值引用,string的构造函数需要改成“move构造函数”,如下所示。这样一来,使得对某个stirng的右值引用可以单纯地从右值复制其内部C-style的指针到新的string,然后留下空的右值。这个操作不需要内存数组的复制,而且空的暂时对象的析构也不会释放内存。其更有效率。
C++ 11 STL 标准库
C++ STL库在2003年经历了很大的整容手术 Library Technical Report 1 (TR1)。 TR1 中出现了很多新的容器类 (unordered_set,
unordered_map,
unordered_multiset, 和
unordered_multimap) 以及一些新的库支持诸如:正则表达式, tuples,函数对象包装,等等。 C++11 批准了 TR1 成为正式的C++标准,还有一些TR1 后新加的一些库,从而成为了新的C++ 11 STL标准库。这个库主要包含下面的功能:
线程库
这们就不多说了,以前的STL饱受线程安全的批评。现在好 了。C++ 11 支持线程类了。这将涉及两个部分:第一、设计一个可以使多个线程在一个进程中共存的内存模型;第二、为线程之间的交互提供支持。第二部分将由程序库提供支持。大家可以看看promises and futures,其用于对象的同步。 async() 函数模板用于发起并发任务,而 thread_local 为线程内的数据指定存储类型。更多的东西,可以查看
Anthony Williams的 Simpler Multithreading in C++0x.
新型智能指针
C++98 的知能指针是
auto_ptr, 在C++ 11中被废弃了。C++11 引入了两个指针类: shared_ptr 和
unique_ptr。 shared_ptr只是单纯的引用计数指针,
unique_ptr 是用来取代提供auto_ptr。 [code]unique_ptr
auto_ptr大部份特性,唯一的例外是
auto_ptr的不安全、隐性的左值搬移。不像
auto_ptr,
unique_ptr可以存放在
C++0x 提出的那些能察觉搬移动作的容器之中。
为什么要这么干?大家可以看看《More Effective C++》中对 auto_ptr的讨论。
新的算法
定义了一些新的算法:
all_of(),
any_of()和
none_of()。
iota()可以用来创建递增的数列。如下例所示:
benchmark tests。原文还引用Stroustrup 的观点:C++11 是一门新的语言——一个更好的 C++。
如果把所有的改变都列出来,你会发现真多啊。我估计C++ Primer那本书的厚度要增加至少30%以上。C++的门槛会不会越来越高了呢?我不知道,但我个人觉得这门语言的确是变得越来越令人望而却步了。(想起了某人和我说的一句话——学技术真的是太累了,还是搞方法论好混些?)
(全文完)
相关文章推荐
- 详解C++11中值得关注的几大变化(1)
- C++11 中值得关注的几大变化(详解)
- C++11 中值得关注的几大变化(详解)
- C++11 中值得关注的几大变化(详解)
- C++11 中值得关注的几大变化(详解)
- C++11 中值得关注的几大变化(转-详解)
- C++11 中值得关注的几大变化(详解)
- C++11 中值得关注的几大变化(详解
- C++11 中值得关注的几大变化(详解)
- C++11 中值得关注的几大变化(详解)
- C++11 中值得关注的几大变化(详解)
- C++11 中值得关注的几大变化(详解)
- C++11 中值得关注的几大变化(详解)
- C++11 中值得关注的几大变化(详解) 转
- C++11 中值得关注的几大变化(详解)
- C++11 中值得关注的几大变化(详解)
- C++11 中值得关注的几大变化(详解)
- 详解C++11中值得关注的几大变化
- 【引用酷壳】C++11 中值得关注的几大变化(详解)
- C++11 中值得关注的几大变化(详解)