1. 关键字及新语法

1.1 auto关键字

  auto并没有让C++成为弱类型语言,也没有弱化变量什么,只是使用auto的时候,编译器根据上下文情况,确定auto变量的真正类型。

  auto在C++14中可以作为函数的返回值,因此auto AddTest(int a, int b)的定义是没问题的。

  auto作为函数返回值时,只能用于定义函数,不能用于声明函数(编译无法通过)。但如果把实现写在头文件中,可以编译通过,因为编译器可以根据函数实现的返回值确定auto的真实类型。如果读者用过inline类成员函数,这个应该很容易明白,此特性与inline类成员函数类似。

1.2 nullptr关键字及用法

  NULL有问题:

//示例代码1.0 http://www.cnblogs.com/feng-sc/p/5710724.html
class Test
{public:void TestWork(int index){std::cout << "TestWork 1" << std::endl;}void TestWork(int * index){std::cout << "TestWork 2" << std::endl;}
};int main()
{Test test;test.TestWork(NULL);test.TestWork(nullptr);
}

  NULL在c++里表示空指针,看到问题了吧,我们调用test.TestWork(NULL),其实期望是调用的是void TestWork(int * index),但结果调用了void TestWork(int index)。但使用nullptr的时候,我们能调用到正确的函数。

1.3 for循环语法
int main()
{vector<int> mvec={1,2,3,4,5,6};for(auto item:mvec)cout<<item<<" ";
}

2. STL容器新增

2.1 std:array

  std::array跟数组并没有太大区别,相对于数组,增加了迭代器等函数.

2.2 std:forward_list

  线性表,与list(双向链表)区别在于它是单向链表。我们在学习数据结构的时候都知道,链表在对数据进行插入和删除是比顺序存储的线性表有优势,因此在插入和删除操作频繁的应用场景中,使用list和forward_list比使用array、vector和deque效率要高很多。

2.3 std::unordered_map

  std::unordered_map与std::map用法基本差不多,但STL在内部实现上有很大不同,std::map使用的数据结构为二叉树,而std::unordered_map内部是哈希表的实现方式,哈希map理论上查找效率为O(1)。但在存储效率上,哈希map需要增加哈希表的内存开销。

2.4 std::unordered_set

  std::unordered_set的数据存储结构也是哈希表的方式结构,除此之外,std::unordered_set在插入时不会自动排序,这都是std::set表现不同的地方。

3. 多线程

3.1 std::thread

  std::thread为C++11的线程类,使用方法和boost接口一样,非常方便,同时,C++11的std::thread解决了boost::thread中构成参数限制的问题。

3.2 std::atomic

  std::atomic为C++11分装的原子数据类型。从功能上看,简单地说,原子数据类型不会发生数据竞争,能直接用在多线程中而不必我们用户对其进行添加互斥资源锁的类型。从实现上,大家可以理解为这些原子类型内部自己加了锁。

3.3 std::condition_variable

  C++11中的std::condition_variable就像Linux下使用pthread_cond_wait和pthread_cond_signal一样,可以让线程休眠,直到被唤醒,再重新执行。线程等待在多线程编程中使用非常频繁,经常需要等待一些异步执行的条件的返回结果。

4. 智能指针内存管理

  在内存管理方面,C++11的std::auto_ptr基础上,移植了boost库中的智能指针的部分实现,如std::shared_ptr、std::weak_ptr等,当然,想boost::thread一样,C++11也修复了boost::make_shared中构造参数的限制问题。

  智能指针只是用对象去管理一个资源指针,同时用一个计数器计算当前指针引用对象的个数,当管理指针的对象增加或减少时,计数器也相应加1或减1,当最后一个指针管理对象销毁时,计数器为1,此时在销毁指针管理对象的同时,也把指针管理对象所管理的指针进行delete操作。

4.1 std::shared_ptr

  std::shared_ptr包装了new操作符动态分别的内存,可以自由拷贝复制,基本上是使用最多的一个智能指针类型。

  • std::make_shared封装了new方法,boost::make_shared之前的原则是既然释放资源delete由智能指针负责,那么应该把new封装起来,否则会让人觉得自己调用了new,但没有调用delete,似乎与谁申请,谁释放的原则不符。C++也沿用了这一做法。
  • 随着引用对象的增加std::shared_ptr p2 = p1,指针的引用计数有1变为2,当p2退出作用域后,p1的引用计数变回1,当main函数退出后,p1离开main函数的作用域,此时p1被销毁,当p1销毁时,检测到引用计数已经为1,就会在p1的析构函数中调用delete之前std::make_shared创建的指针。
4.2 std::weak_ptr

  为了解决std::shared_ptr在相互引用的情况下出现的问题而存在的,与std::shared_ptr最大的差别是在赋值时,不会引起智能指针计数增加。

std::shared_ptr相互引用的问题示例:

创建了一个TestA和一个TestB的对象,但在整个main函数都运行完后,都没看到两个对象被析构。代码中智能指针ptr_a中引用了ptr_b,同样ptr_b中也引用了ptr_a,在main函数退出前,ptr_a和ptr_b的引用计数均为2,退出main函数后,引用计数均变为1,也就是相互引用。相互引用导致的问题就是释放条件的冲突,最终也可能导致内存泄漏。

//示例代码1.0 http://www.cnblogs.com/feng-sc/p/5710724.html
#include <memory>
class TestB;
class TestA
{public:TestA(){std::cout << "TestA()" << std::endl;}void ReferTestB(std::shared_ptr<TestB> test_ptr){m_TestB_Ptr = test_ptr;}~TestA(){std::cout << "~TestA()" << std::endl;}
private:std::shared_ptr<TestB> m_TestB_Ptr; //TestB的智能指针
}; class TestB
{public:TestB(){std::cout << "TestB()" << std::endl;}void ReferTestB(std::shared_ptr<TestA> test_ptr){m_TestA_Ptr = test_ptr;}~TestB(){std::cout << "~TestB()" << std::endl;}std::shared_ptr<TestA> m_TestA_Ptr; //TestA的智能指针
};int main()
{std::shared_ptr<TestA> ptr_a = std::make_shared<TestA>();std::shared_ptr<TestB> ptr_b = std::make_shared<TestB>();ptr_a->ReferTestB(ptr_b);ptr_b->ReferTestB(ptr_a);return 0;
}

std::weak_ptr如何解决相互引用的问题:

  ptr_a 和ptr_b在main函数中退出前,引用计数均为1,也就是说,在TestA和TestB中对std::weak_ptr的相互引用,不会导致计数的增加。在TestB析构函数中,调用std::shared_ptr tmp = m_TestA_Ptr.lock(),把std::weak_ptr类型转换成std::shared_ptr类型,然后对TestA对象进行调用。

//示例代码1.0 http://www.cnblogs.com/feng-sc/p/5710724.html#include <memory>
class TestB;
class TestA
{public:TestA(){std::cout << "TestA()" << std::endl;}void ReferTestB(std::shared_ptr<TestB> test_ptr){m_TestB_Ptr = test_ptr;}void TestWork(){std::cout << "~TestA::TestWork()" << std::endl;}~TestA(){std::cout << "~TestA()" << std::endl;}
private:std::weak_ptr<TestB> m_TestB_Ptr;
};class TestB
{public:TestB(){std::cout << "TestB()" << std::endl;}void ReferTestB(std::shared_ptr<TestA> test_ptr){m_TestA_Ptr = test_ptr;}void TestWork(){std::cout << "~TestB::TestWork()" << std::endl;}~TestB(){std::shared_ptr<TestA> tmp = m_TestA_Ptr.lock();tmp->TestWork();std::cout << "2 ref a:" << tmp.use_count() << std::endl;std::cout << "~TestB()" << std::endl;}std::weak_ptr<TestA> m_TestA_Ptr;
};int main()
{std::shared_ptr<TestA> ptr_a = std::make_shared<TestA>();std::shared_ptr<TestB> ptr_b = std::make_shared<TestB>();ptr_a->ReferTestB(ptr_b);ptr_b->ReferTestB(ptr_a);std::cout << "1 ref a:" << ptr_a.use_count() << std::endl;std::cout << "1 ref b:" << ptr_a.use_count() << std::endl;return 0;
}

5. C++14 新特性

  C++14 常用新特性总结(https://blog.csdn.net/chenweiyu11962/article/details/90578429)

参考:

C++11常用特性的使用经验总结(https://www.cnblogs.com/feng-sc/p/5710724.html)


欢迎扫描二维码关注微信公众号 深度学习与数学 [每天获取免费的大数据、AI等相关的学习资源、经典和最新的深度学习相关的论文研读,算法和其他互联网技能的学习,概率论、线性代数等高等数学知识的回顾]

【一天一个C++小知识】012.C++11常用新特性汇总相关推荐

  1. 安卓期末作品小项目_每日一个财务小知识——洞悉洞晰财务报告第一季

    财务报告 洞悉洞晰财务报告 目录 01/账务报告概述 02/资产负债表 03/利润表 04/现金流量表 05/所有者权益变动表 06/附注 一.财务报告概述 (一)财务报告及其目标 财务报告是指企业对 ...

  2. 大数据技术之_11_HBase学习_03_HBase 实战之谷粒微博(练习API) + 扩展知识(布隆过滤器+HBase2.0 新特性)

    大数据技术之_11_HBase学习_03 第8章 HBase 实战之谷粒微博 8.1 需求分析 8.2 代码实现 第9章 扩展知识 9.1 HBase 在商业项目中的能力 9.2 布隆过滤器 9.3 ...

  3. 专家视角 | 小荷的 Oracle Database 18c 新特性快速一瞥

    作者介绍:何剑敏  大疆创新 互联网事业部 运维部数据库技术团队负责人,曾供职于中国联通,卓望数码,IBM 和 ORACLE ACS 华南团队.多年从事一线的数据库运维工作,有丰富项目经验.维护经验和 ...

  4. 【每天一个Python小知识】用yaml的yaml.safe_load()方法读取配置文件中的参数

    文章目录 ymal安装 配置文件格式 配置文件读取 yaml是专门用来写配置文件的,因其简洁高效而被大众喜爱. ymal安装 python3安装: pip install pyyaml#python2 ...

  5. list赋值给另一个list_Python小知识: List的赋值方法,不能直接等于

    Python中关于对象复制有三种类型的使用方式,赋值.浅拷贝与深拷贝.他们既有区别又有联系,刚好最近碰到这一类的问题,研究下. 一.赋值 在python中,对象的赋值就是简单的对象引用,这点和C++不 ...

  6. 每天一个shell小知识(shell变量)

    目录 shell变量 自定义变量: 变量定义/查看 变量赋值的特殊操作: 双引号 单引号 反撇号 设置变量的作用范围: 特殊变量---环境变量: 位置变量: 预定义变量: shell变量 在各种she ...

  7. 每天一个shell小知识(for)

    目录 For循环语句 For语句的结构 结构 执行流程 实例 For循环语句 在实际工作环境中,经常会遇到某项任务需要多次执行的情况,而每次执行时仅仅是处理的对象不一样,其他命令完全相同.如:根据服务 ...

  8. 【每天一个Python小知识】NumPy中的np.where

    函数形式:a = np.where(b) 功能:找到满足条件的b的索引a. 参数:b是某种条件,要求是np类型. 返回值:a是返回的索引,也是np类型. 举个套娃的例子来更好的了解这个函数: impo ...

  9. 【每天一个Python小知识】NumPy中的np.any

    import numpy as np np.any(np.array) 对矩阵中所有元素做或运算,存在True则返回True 一般在条件判等时使用,如: import numpy as np a = ...

  10. 每天一个sql小知识(2)在oracle中实现MySQL的Limite功能

    oracle无法使用MySQL的Limite操作,可以使用rownum代替 例:select* from stu where rownum<=10;

最新文章

  1. layui上传图片接口
  2. Excel事半功倍的应用
  3. ArcGIS Server 部署与配置
  4. QT的QPainterPath类的使用
  5. python dry原则_关于Python 的这几个技巧,你应该知道
  6. mysql with parser_三十分钟成为 Contributor | 提升 TiDB Parser 对 MySQL 8.0 语法的兼容性...
  7. 目录与文件的权限意义
  8. 解决修改sources.list之后update NO_PUBKEY错误
  9. 《如何建立自己的算法交易事业》读书笔记
  10. 易辅客栈 从零学辅助_如何从零启动辅助项目
  11. python语言实现图像的手绘效果
  12. Linux命令—— expect: command not found
  13. 联想服务器SR650升级网卡固件微码
  14. 众望所归!《觉醒年代》《山海情》成玉兰奖大赢家
  15. Vmware上安装openstack(Queens版)
  16. 【Java】JVM内存回收
  17. {“errcode“:48001,“errmsg“:“api unauthorized, hints: [ req_id: xxxxxxx]“}
  18. 【深度学习小常识】什么是mAP?
  19. DialogBox使用例子
  20. 中兴软创的外包-北京之行

热门文章

  1. CentOS 5.5 使用 EPEL 和 RPMForge 软件库
  2. 在手动安装 Kubernetes 的基础上搭建微服务
  3. 全局异常捕捉用法解析
  4. hdu 6129 Just do it
  5. 创建一个jFinal项目
  6. KVM之五:KVM日常管理常用命令
  7. 常用几个UITableView,UICollectionView  UIScrollView关键点
  8. X64上的IIS調用32位的DLL方法
  9. sql2000下 分页存储过程(一)
  10. JSP中的坑(二):使用include包含jsp文件时contentType中charset的值区分大小写