C++2.0——lambda、 override和final的介绍

Lambda

ISO C++ 11 标准的一大亮点是引入Lambda表达式,Lambda 表达式(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Lambda表达式可以表示闭包(注意和数学传统意义上的不同)。

基本语法如下:

 

[capture list] (parameter list) mutable -> return type { function body }

  • [capture list]:捕捉列表。捕捉列表总是出现在Lambda函数的开始处。实际上,[]是Lambda引出符。编译器根据该引出符判断接下来的代码是否是Lambda函数。捕捉列表能够捕捉上下文中的变量以供Lambda函数使用;
  • (parameter list):参数列表。与普通函数的参数列表一致。如果不需要参数传递,则可以连同括号“()”一起省略;
  • mutablemutable修饰符。默认情况下,Lambda函数总是一个const函数,mutable可以取消其常量性。在使用该修饰符时,参数列表不可省略(即使参数为空);
  • ->return-type:返回类型。用追踪返回类型形式声明函数的返回类型。我们可以在不需要返回值的时候也可以连同符号->一起省略。此外,在返回类型明确的情况下,也可以省略该部分,让编译器对返回类型进行推导;
  • {function body}:函数体。内容与普通函数一样,不过除了可以使用参数之外,还可以使用所有捕获的变量。

lamda表达式,与普通函数,最大的不同,在于拥有捕获列表,捕获列表有一下几种形式:

  • [] 不截取任何变量
  • [&] 截取外部作用域中所有变量,并作为引用在函数体中使用
  • [=] 截取外部作用域中所有变量,并拷贝一份在函数体中使用
  • [=, &foo] 截取外部作用域中所有变量,并拷贝一份在函数体中使用,但是对foo变量使用引用
  • [bar] 截取bar变量并且拷贝一份在函数体重使用,同时不截取其他变量
  • [this] 截取当前类中的this指针。如果已经使用了&或者=就默认添加此选项。

    int id = 0;
    //此时截取了id的值为0,后面调用的时候id为0
    //mutable 表明id是可变的,否则编译不通过
    auto f = [id]() mutable {  cout << "id=" << id << endl;  id++};

    id = 42;
    f();// 0
    f();//1
    f();//2
    cout << "after f() id=" << id << endl;//42

lambda的使用:

1. 用于函数参数

#include <iostream>
#include<algorithm>
#include <vector>

using namespace std;

template <typename T>
using Vec = vector<T, allocator<T>>;

int main() 
{
    Vec<int> vec{1,2,3,4,5,6,7,8,9};
    for_each(vec.begin(),vec.end(),[](int v) { cout << v << endl; });//用作函数参数

    return 0;
}

2. 使用auto来接收一个lambda表达式

当然我们也可以直接使用C++11里面的新特性function来接收lambda表达式,两者等价的,因为auto是自动类型转换,所以在某些场合使用起来更方便。

#include <iostream>
#include<algorithm>
#include <vector>
#include <functional>

using namespace std;


int main() 
{


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

	//[=] 截取外部作用域中所有变量,并拷贝一份在函数体中使用
	function<int(int, int)> add2 = [=](int a, int b) { return a + b; };

	int x = 5, y = 19;
	cout << add(x, y)  << "   "  <<   add2(x,y) << endl;

	return 0;
}

3. 使用lambda表达式来实现递归算法

已知f(1)=1,f(2)=2,那么请实现求f(n)=f(n-1)+f(n-2)的值,此处的n>2 :

#include <iostream>
#include<algorithm>
#include <vector>
#include <functional>

using namespace std;

int main() 
{
	//[&] 截取外部作用域中所有变量,并作为引用在函数体中使用
	function<int(int)> recursion = [&recursion](int n) 
	{
		return n < 2 ? 1 : (recursion(n - 1) + recursion(n - 2));
	};

	cout << "recursion(2):" << recursion(2) << endl;
	cout << "recursion(3):" << recursion(3) << endl;
	cout << "recursion(4):" << recursion(4) << endl;

	return 0;
}

override

override用于明确要重写父类的虚函数上,相当于告诉编译器这个函数就是要重写父类虚函数这样一个意图,让编译器帮忙检查,而没有这个关键字,编译器是不会帮你检查的。

#include <iostream>

using namespace std;

class Base {
public:
	virtual void func(int) { cout << "Base::func(int)" << endl; };
};

class Derived : public Base
{
public:
	//本意是写重写基类的func,但是函数参数错误,并未实现重写,并且编译器也未有期望的任何提示
	void func(float) { cout << "Derived::func(float)" << endl; }
};

class Derived2 : public Base 
{
public:
	//error C3668: “Derived2::func”: 包含重写说明符“override”的方法没有重写任何基类方法
	void func(float) override { cout << "Derived2::func(float)" << endl; }
};

int main() 
{


	return 0;
}

final

final新增两种功能:(1)、禁止基类被继承,(2)、禁止虚函数被重写;


class Base1 final {};

class Base2 
{
public:
	virtual void func() final {}
};

//error C3246: “Derived1”: 无法从“Base”继承,因为它已被声明为“final”
class Derived1 : public Base1 {};

class Derived2 : public Base2 
{
public:
	//error C3248: “Base2::func”: 声明为“final”的函数无法被“Derived2::func”重写
	void func() {}
};

 

以上参考:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值