常见的C++11新特性
1、初始化列表
传统的C++中,针对不同的类型有不同类型的初始化,下面看几组类型的初始化
// 普通变量初始化
int nType = int(3);
// 普通数组初始化
int nArray[] = {1,2,3,4};
// POD类型初始化 (plain old data,没有构造、析构和虚函数的类或结构体)
struct MyStruct{
QString sName;
int nType;
} Simple = {"Kevin", 2};
// 类对象的初始化
class MyClass{
public:
QString sName;
int nType;
};
MyClass classA = MyClass{"Kevin", 2};
为了解决不同类型的初始化,C++11首先把初始化列表的概念绑定到了类型上,并将其称之为 initializer_list,允许构造函数或其他函数像参数一样使用初始化列表,这就为类对象的初始化与普通数组和 POD 的初始化方法提供了统一的桥梁。
// 通过initializer_list初始化列表初始化变量
class MyClass{
public:
MyClass(string name):sName(name),c{2,3,4,2}{};
private:
string sName;
int c[4];
int *pNumber = new int[]{1,2,3,4};
vector<int> vec = {1,2,3};
map<int, string> curmap= {{18, "Kevin"},{20, "Tom"}};
};
MyClass Obj{"Jim"}; // 初始化实例化对象
也许有的人会问,C++标准模板库中提供了很多容器,如vector或list,那为什么不直接使用容器自己的构造函数呢,为什么还要使用C++11的initializer_list呢?
接下来我们来看一个例子,假如现在我需要判断一组数据中的最大值,那么该如何计算呢?
在c++11之前,max函数的源程序是这样的:
// 最大值
template <class T> const T& max (const T& a, const T& b);
template <class T, class Compare> const T& max (const T& a, const T& b, Compare comp);
在c++11之后,max函数的源程序是这样的:
template <class T> T max (initializer_list<T> il);
template <class T, class Compare> T max (initializer_list<T> il, Compare comp);
这说明了什么,说明通过对类模板initializer_list的支持,在计算最大值可以传递更多的参数了。
cout << max({ 54,16,48,5,89}) << endl; //输出89
尽管有时候通过vector或list容器也可以实现这些功能,但开销最小的最直接的方法是使用initializer_list。
初始化列表initializer_list除了用于构造函数外,还可以作为函数的参数。下面编写一个函数sum来求和,演示该模板类作为函数参数的使用。
#include<iostream>
#include<initializer_list>
using namespace std;
double sum(initializer_list<int> L){
double tol = 0.0;
for(auto p = L.begin(); p != L.end(); p++){
tol += *p;
}
return tol;
}
int main(){
int nTol = sum({1.0, 2, 3, 4.5});
cout << nTol <<endl;
return 0;
}
2、范围for或foreach
C++ 11提供了一个特殊版本的 for 循环,在很多情况下,它都可以简化数组的处理,这就是基于范围的 for 循环。在使用基于范围的 for 循环处理数组时,该循环可以自动为数组中的每个元素迭代一次。首先来看下传统数组遍历和范围for的写法。
int numbers[] = {3, 6, 9, 12, 15};
// 传统写法
for (int i=0; i<numbers.size(); ++i)
{
cout << i << endl;
}
// 范围for写法
for (auto nVal : numbers)
{
cout << nVal << endl;
}
// foreach写法
foreach (auto nVal , numbers)
{
cout << nVal << endl;
}
与传统的for循环相比,范围for或foreach不会考虑元素的下标,但是,如果出于某些目的需要使用元素下标时,基于范围的 for 循环或foreach就不能使用了。另外,当遍历多个变量时,也是不能使用的。
参考文章
http://c.biancheng.net/view/1416.html
http://www.cplusplus.com/reference/