c++11新特性

  1. 关键字及新语法 1.1. auto 关键字及用法 1.2. nullptr 关键字及用法 1.3. for 循环语法
  2. 智能指针内存管理 4.1. std::shared_ptr 4.2. std::weak_ptr
  3. STL 容器 2.1. std::array 2.2. std::forward_list 2.3. std::unordered_map 2.4. std::unordered_set
  4. 多线程 3.1. std::thread 3.2. std::atomic 3.3. std::condition_variable
  5. 其他 5.1. std::function、std::bind 封装可执行对象 5.2. lambda 表达式

1. nullptr

nullptr 出现的目的是为了替代 NULL。在某种意义上来说,传统 C++ 会把 NULL、0 视为同一种东西,这取决于编译器如何定义 NULL,有些编译器会将 NULL 定义为 ((void*)0),有些则会直接将其定义为 0。

2. 类型推导

C++11 引入了 auto 和 decltype 这两个关键字实现了类型推导,让编译器来操心变量的类型。

auto
auto 在很早以前就已经进入了 C++,但是他始终作为一个存储类型的指示符存在,与 register 并存。在传统 C++ 中,如果一个变量没有声明为 register 变量,将自动被视为一个 auto 变量。而随着 register 被弃用,对 auto 的语义变更也就非常自然了。使用 auto 进行类型推导的一个最为常见而且显著的例子就是迭代器。在以前我们需要这样来书写一个迭代器:

for(vector<int>::const_iterator itr = vec.cbegin(); itr != vec.cend(); ++itr)
而有了 auto 之后可以:

// 由于 cbegin() 将返回 vector<int>::const_iterator    所以 itr 也应该是 vector<int>::const_iterator 类型
for(auto itr = vec.cbegin(); itr != vec.cend(); ++itr);
一些其他的常见用法:auto i = 5;             // i 被推导为 int     auto arr = new auto(10) // arr 被推导为 int *
注意:auto 不能用于函数传参,因此下面的做法是无法通过编译的(考虑重载的问题,我们应该使用模板):

int add(auto x, auto y);

decltype
decltype 关键字是为了解决 auto 关键字只能对变量进行类型推导的缺陷而出现的。它的用法和 sizeof 很相似:

在此过程中,编译器分析表达式并得到它的类型,却不实际计算表达式的值。有时候,我们可能需要计算某个表达式的类型,例如:  auto x = 1;    auto y = 2;         decltype(x+y) z;

3. 区间迭代

基于范围的 for 循环
C++11 引入了基于范围的迭代写法,我们拥有了能够写出像 Python 一样简洁的循环语句。
最常用的 std::vector 遍历将从原来的样子:

// & 启用了引用
for(auto &i : arr) {    
    std::cout << i << std::endl;
}


4.智能指针

核心思想:为防止内存泄露等问题,用一个对象来管理野指针,使得在该对象构造时获得该指针管理权,析构时自动释放(delete).
基于此思想C++98提供了第一个智能指针:auto_ptr
auto_ptr基于所有权转移的语义,即将一个就的auto_ptr赋值给另外一个新的auto_ptr时,旧的那一个就不再拥有该指针的控制权(内部指针被赋值为null),那么这就会带来一些根本性的破绽:

  • 函数参数传递时,会有隐式的赋值,那么原来的auto_ptr自动失去了控制权
  • 自我赋值时,会将自己内部指针赋值为null,造成bug

因为auto_ptr的各种bug,C++11标准基本废弃了这种类型的智能指针,转而带来了三种全新的智能指针:

  • shared_ptr,基于引用计数的智能指针,会统计当前有多少个对象同时拥有该内部指针;当引用计数降为0时,自动释放
  • weak_ptr,基于引用计数的智能指针在面对循环引用的问题将无能为力,因此C++11还引入weak_ptr与之配套使用,weak_ptr只引用,不计数
  • unique_ptr: 遵循独占语义的智能指针,在任何时间点,资源智能唯一地被一个unique_ptr所占有,当其离开作用域时自动析构。资源所有权的转移只能通过std::move()而不能通过赋值

5.lambda表达式

lambda表达式是匿名函数,可以认为是一个可执行体functor,语法规则如下:

lambda 表达式用于定义并创建匿名的函数对象,以简化编程工作。可以拿来当作 inline 函数使用。lambda 的语法形式如下:

[捕获区](参数区){代码区};

auto add = [](int a, int b) {return a + b};

就我的理解而言,捕获的意思即为将一些变量展开使得为lambda内部可见,具体方式有如下几种

  • [a,&b] 其中 a 以复制捕获而 b 以引用捕获。
  • [this] 以引用捕获当前对象( *this
  • [&] 以引用捕获所有用于 lambda 体内的自动变量,并以引用捕获当前对象,若存在
  • [=] 以复制捕获所有用于 lambda 体内的自动变量,并以引用捕获当前对象,若存在
  • [] 不捕获,大部分情况下不捕获就可以了

一般使用场景:sort等自定义比较函数、用thread起简单的线程。

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值