这篇文章记录下部分C++11的新特性,有很多常用的也有很多一下子接受不了的。
int a=0; int a={0}; int a{0}; int a(0);
上面是四种初始化方式,其中花括号初始化已经在c++11中全面使用,有以下特点。
float a=3.14; int b{a},b={a};//错误,不执行隐式转换,因为存在丢失信息的风险 int b(a);//正确,执行了隐式转换,且丢失了信息。
nullprt是一个空指针值,下面几个式子是等效的。
int *p1=nullptr; int *p2=0; int *p3 = NULL;//需要头文件stdlib.h,里面定义了预处理变量NULL,值为0
将变量声明为constexpr类型来确定它是一个常量表达式。
例如:
constexpr int mf = 20; constexpr int limit = mf+1; constexpr int a = res();//res必须返回一个constexpr型
有两种方法可以定义类型别名。
1. 利用typedef
2.利用using as(c++11)
typedef double base;//base是double的别名 using base = double;//同上
c++也能不管变量类型了,喜大普奔。
auto i = 1,*p=&i;//正确 auto j = 0,*q = 3.14;//错误,类型不一致
有时候我们想从一个函数的返回值知道变量的类型,又不想用返回值赋值变量。C++11就引入了第二种类型说明符decltype。
int func(){return 1;} int x=2; decltype(func()) num = x;//利用func的返回类型声明变量并用x的值赋值
此过程并不真正调用func函数。
c++11多了两个与容器的函数同名的begin和end函数。
int arr = {1,2,3,4,5}; int *pts = begin(arr);//指向首地址 int *pte = end(arr);//指向尾元素的下一位置指针
当我们不知道要传多少个参数給函数,但是却知道了这些参数的类型时,可以用initializer_list类型的形参。
(其实感觉和vector一个样,唯一不同的是initializer_list的元素值只能是常值)
capture listshii是一个捕捉列表,是lambda函数所在函数中的临时变量的列表,一般为空。
(我们可以忽略参数列表和返回类型,但是必须要注意函数体和捕捉列表,且lambda必须使用尾置返回)
std::vector<int> some_list; int total = 0; for (int i = 0; i < 5; ++i) some_list.push_back(i);
//lambda用于for循环时 std::for_each(begin(some_list), end(some_list), [&total](int x) { total += x; });
另一个例子:
C++中动态内存的管理是用new和delete来完成的。但是动态内存的使用很容易出问题,比如忘记回收空间,产生内存泄漏;或者指针还要引用的情况下就释放了它。为了更容易更安全的管理动态内存,新标准提供了两种智能指针,它们的行为类似普通指针,区别是它负责自动释放所指向的对象。
shared_ptr:允许多个指针指向同一个对象。
unique_prt:独占所指向的对象。
还有一个名为weak_ptr的伴随类,是一个弱引用,指向shared_ptr所管理的对象。
make_shared函数
最安全的分配和使用动态内存的方法为调用一个叫make_shared的函数。此函数在动态内存中分配一个对象并初始化它,返回此对象的shared_ptr。
对于上述cin<<i语句,因为istream里没有定义<<,该代码可能cin会被转换成bool,再进一步变成int,则<<会变成左移运算符,与我们的预期大大相反。
为了避免上述的事情发生,c++11引入了显式类型转换符explicit。
C++拥有了一个正则表达式库(RE库)。