1. 指针控制——nullptr

从0到NULL再到nullptr

最开始时,典型的初始化指针是将其指向一个空的位置,比如0。因为大多数计算机通常不允许程序员往地址为0的空间写入内容,一旦执行即程序退出。
因此一般会定义int* myptr_=0; int myptr_=NULL
一般情况下NULL是个宏定义:

  1. #undef NULL
  2. #if defined(__cplusplus)
  3. #define NULL 0
  4. #else
  5. #define NULL((void*) 0)
  6. #endif

:::info 这会带来二义性,字面常量0的二义性:

  • 整型
  • 无类型指针 :::

    nullptr

    C++11中,出于兼容性考虑,定义了nullptr,指针空值类型常量。

    2. 默认函数的控制

    C++中声明自定义的类,编译器会默认帮助程序员生成他们没有自定义的成员函数:

  • 构造

  • 拷贝构造
  • 拷贝赋值(operator=)
  • 移动构造
  • 移动拷贝
  • 析构

但是一旦程序员实现了这些函数的自定义版本,编译器不再为该类生成默认版本。

  • C++11中,标准提供了新的机制来控制默认版本函数的生成。重用了default关键字,可以默认函数定义或是声明时加上=default来显示地指定使用默认版本。
  • 此外可以通过=delete来指定不生成缺省的版本。

    3. lambda函数

    语法定义:

    1. [capture](parameters) mutable ->return-type{statement}
  • capture:捕获列表,[]是lambda的引出符,编译器根据该符号判断下面的代码是否是lambda函数。

  • parameters:参数列表,可以省略如不需要。
  • mutable:默认lambda是const函数
  • ->return-type:返回类型
  • statement:函数体

lambda函数可以通过捕获列表访问一些上下文中的数据,捕获列表描述了上下文中哪些数据可以被lambda函数使用,以及具体的使用方式(以值传递还是引用传递)
捕获列表有以下几种形式:

  • [var] 值传递的方式捕捉变量var
  • [=] 值传递的方式捕获所有父作用域的变量,包含this
  • [&var] 引用传递的方式捕获变量var
  • [&] 引用传递的方式捕获所有父作用域的变量,包含this
  • [this] 值传递的方式捕获this指针

并且可以通过一些组合表示复杂的意义
e.g.,[=,&a,&b]: 引用传递的方式捕获变量a和b,值传递的方式捕获其他变量。

lambda与仿函数

仿函数一般又称作函数对象,简单来说就是重定义了成员函数operator(),的一种自定义类型对象。
lambda与仿函数有相同的内涵:都可以捕获一些变量作为初始状态,并且接受参数进行运算。
实际上仿函数是编译器实现lambda函数的一种方式。

  • 在C++11中,lambda并不是仿函数的完全替代者,很大程度上是因为lambda的捕捉列表的限制造成的,现有的标准中,捕捉列表仅仅能捕获父作用域的自动变量,对于超出此范围的变量是不予捕获的,
  • 而仿函数可以被定义在不同作用域范围内取得初始值,因此可以跨作用域共享。

总的来说lambda被设计的目的就是为了要就地书写就地使用。

lambda仿函数与函数指针

  1. class Test{
  2. pubilc:
  3. static bool greate(const ListNode* a,const ListNode* b){
  4. return a->val>b->val;
  5. }
  6. class Cmp{
  7. public:
  8. bool operator()(const ListNode* a,const ListNode* b){
  9. return a->val>b->val;
  10. }
  11. };
  12. int getMin(){
  13. priority_queue<ListNode*,vector<ListNode*>,decltype(*greate)> pq1(*greate);
  14. //用函数指针的
  15. auto cmp=[](const ListNode* a,const ListNode* b)->bool {return a->val>b->val;}
  16. priority_queue<ListNode*,vector<ListNode*>,decltype(cmp)> pq1(cmp);
  17. //用lambda
  18. priority_queue<ListNode*,vector<ListNode*>,Cmp> pq;
  19. //用仿函数的
  20. }
  21. };