c++11里面有很多的新特性,之前在项目代码中也使用过很多次,但是没有系统的整理过,在这里整理一下我特别喜欢的一些c++11的新特性,这些也是我使用频率比较高的特性嘿嘿!
auto表达式
我一般在容器迭代的时候使用auto,这样就不需要定义迭代器的类型。
for(auto it = vec.begin(); it != vec.end(); it++)
{
cout<<*it<<endl;
}
for(auto ele:vec)
{
cout<<ele<<endl;
}
使用nullptr而不是NULL|或者0
nullptr的基础是c++定义的一个类。
NULL在c++里面就是数字0。
NULL在纯c当中是void*。
函数可能在整型和指针型之间重载,为了避免调用到错误的函数,使用nullptr。
很多时候通不过编译,如果通过编译也没办法调用int*的函数,使用nullptr可以避免这个问题。
override关键字
由于子类重写父类的虚函数经常会出现错误,所以c++11加了这个override声明,子类重写父类虚函数的时候有以下的要求必须满足
- 基类的函数必须是虚函数
- 函数名字必须一样,析构函数除外
- 基类和派生类的函数的参数形参必须是一致的。
- 基类和派生类的函数常量性必须完全相同。
- 返回值和异常必须是可以兼容的
- 函数的引用修饰词必须完全相同。
加入override关键字之后可以检查出为什么重载没有成功,是哪个地方出了问题。
delete关键字
有的时候,我们的类是不支持拷贝的,不支持赋值操作的,这个时候c++98的做法是将拷贝构造函数和赋值构造函数设置为private类型的,但是成员函数,友员函数还是可以访问这些函数,只是链接阶段是会报错的。
c++11提供了更好的方法,使用“=delete”来将赋值函数和拷贝构造函数设置为删除函数。这样的话无论什么函数都无法调用删除函数。
delete关键字相当于private还有一个好处是因为 private只针对于类成员函数,但是delete可以delete成员函数和普通函数。
智能指针
| 智能指针 | 备注 |
|---|---|
| auto_ptr | 可以赋值,前者失去所有权,无法放置在容器中 |
| unique_ptr | 适用于专属所有权的资源,不允许拷贝,不允许赋值,转换成shared_ptr是很简单的 |
| shared_ptr | 共享所有权,使用引用计数,引用计数为0的时候释放资源,问题:循环引用导致资源没有办法释放 |
| weak_ptr | 配合shared_ptr使用,解决循环引用的问题,控制块当中的弱引用实现 |
使用智能指针需要注意以下几点
- 拒绝使用裸指针变量(裸指针变量可能会被给到两个智能指针,二次释放等出现未定义的错误。)
- 用make_shared来取代new出来的结果,原因如下
(1)减少代码的冗余
//使用make_shared函数
auto p(std::make_shared<asr>());
//不使用make_shared函数
std::shared_ptr<asr> p(new asr);
(2)资源的泄漏
(3)减少一次内存的分配
std::shared_ptr p(new asr);
这个 new对象的时候要分配一次内存 构造智能指针的时候要分配控制块的内存一次,这里就涉及到了两次内存的分配。
auto p(std::make_shared());
而使用make函数可以一次分配,这样的话减少了内存的分配,可以提高性能。
move语意
move实际不做任何搬运的操作,能够实现move是因为类中重载了参数为右值引用的拷贝构造函数,而move函数做的工作就是将左值转换成右值引用,这样的话我们就会优先选择具有move语意的拷贝构造函数!!!
具有move语意的拷贝构造函数实际上没有做深拷贝的动作,而是通过交换指针来将右值的东西偷走。