一、auto标识符(自动类型推导)
使用auto类型,编译器可以根据变量初始值和表达式来推断变量的类型;下面是auto推断的规则:
1、基本类型推断
auto i = 42; // i 的类型是 int
auto d = 3.14; // d 的类型是 double
2、字符串字面量
auto s="hello"; //s的类型是const char*
3、引用类型推断
int a=10;
int &b=a;
auto c=b; //c为int类型
auto& d=b; //d为int&类型
4、指针类型推断
int q=10;
int*p =&q;
auto t=p; //p的类型为 int*
5、常量和限定符
const int a=10;
auto b=a; //b为int类型
const auto c=b; //c为const int类型
6、初始化列表
auto lst={1,2,3,4,5}; //lst类型为initializer_list<int>类型
7、容器类型
vector<int> nums={1,2,3,4,5};
auto vec=nums; //vec的类型是vector<int>
cout<<vec[0]<<endl; //输出为1
8、数组类型
int arr[]={1,2,3,4,5};
auto nums=arr;//nums的类型是int*
9、string类
string s="hello";
auto ss=s; //ss为string类型
二、decltype标识符(类型推断符)
功能与auto一样都用与推断变量的类型,但是两者存在区别:
- decltype主要用于获取表达式类型,而auto主要是为了声明和初始化变量;
- decltype保留常量限定符和引用,而auto不保留;
- auto要求变量必须初始化,而decltype可初始化也可以不初始化;
- decltype的类型与表达式的值无关,只和表达式的类型有关,而auto是根据表达式的值进行推断的;
例如:
int a=10;
const int& b=a;
decltype(b) c;//c为const int&类型;
三、lambda表达式
lambda函数经常与算法函数(例如sort函数、count_if 函数)结合使用,避免传统函数定义的繁琐语法结构,简化代码;
首先要知道lambda表达式的结构:
[捕获列表](参数列表)->返回类型 {
函数体
}
捕获列表:用于捕获外部变量,可以按值或者按引用捕获
例如:
int main(){
vector<int> nums={2,1,5,4,3};
sort(nums.begin(),nums.end(),[](int a,int b)->bool{return a<b;});//从小到大排序
int pivot=5;
int n=count_if (nums.begin(),nums.end(),[pivot](int n)->bool{return n<pivot});//n=4,计算数组中小于5的数字的个数
return 0;
}
四、范围for语句
for(declaration:expression){
statement
}
参数含义:expression,必须是一个序列,例如vector、string、数组等能够拥有迭代器成员的;
declaration:此处声明一个变量,常用auto进行声明;
int main(){
vector<int> nums={1,2,3,4,5};
for (auto num:nums)
cout<<num<<endl;
return 0;
}
五、标准库函数move()函数–移动拷贝构造函数
通过move()函数获取变量的右值引用,从而可以调用对象的移动拷贝构造函数和移动复制构造函数;
六、智能指针
不再过多赘述
七、使用或者禁用对象的默认函数
在学习面向对象编程时,如果在类中没有定义构造函数、拷贝构造函数和析构函数,则编译器会为对象自动生成默认函数,如果使用了用户自定义的构造函数,那么编译器就不会再使用默认的构造函数,也就是说默认的构造函数与自定义的构造函数是不共存的。但是有些场景下既需要默认函数又需要自定义构造函数,在c++11中允许在用户自定义构造函数的情况下仍可以使用默认函数;这一点通过使用**default函数(=default)**实现,具体如下:
class MyClass {
public:
MyClass() = default; // 显式保留默认构造函数
MyClass(int x) : value(x) {} // 自定义构造函数
private:
int value;
};
另外,有一种场景下,不允许使用拷贝构造函数,例如智能指针中的unique_ptr,所以要禁用对象的默认拷贝构造函数,下面就是禁用拷贝构造函数的例子;
class MyClass {
public:
MyClass() = default; // 显式保留默认构造函数
MyClass(int x):value(x){}
MyClass(const MyClass& obj)=delete; //禁用拷贝构造函数
private:
int value;
};
int main(){
MyClass p(222);
MyClass q=p; //出现错误,因为拷贝构造函数已经被禁用
return 0;
}
八、constexper关键字(常量表达式)
通过constexper关键字可以使得特定的表达式在编译时进行计算,从而减小程序运行时的开销;
这里就不再过多叙述;
九、nullptr关键字(空指针常量)
传统的c++代码中NULL既可以代表0又可以代表空指针,这在有些重载函数中可能会出现歧义,所以在c++11中引入nullptr只能代表空指针,使得代码更加安全,更加易于理解;