【C++11新特性】| 【05】nullptr、deleted、lambda解析

1、nullptr

使用指针时,务必需要将其初始化,否则将会是一个悬挂指针;

【NULL】:传统的C中NULL被定义为字面量0或者定义为无类型指针(void*);
【nullptr】:C++11中,nullptr是一个指针空值类型的常量,指针空类型为nullptr_t,而不是指针;
	==> typedef decltype(nullptr) nullptr_t;
	- 当在模板推导时,不会被推导为指针类型;
	- 不是一个(void*)0的别名;
	- 是一个编译期常量;
	- 能够隐式转化到其他指针类型;
	- 其地址不能被用户获取(为右值常量);
【nullptr_t】:声明一个指针空值类型的变量;
	- 使用该类型定义的数据都是等价的;
	- 该类型可以隐式转换为任意指针,但不能转换为非指针类型;
	- 不适合算术运算表达式,但满足关系表达式;
	- 其地址能够被用户使用;

2、默认函数的控制

类的默认函数:
	成员函数 == > 构造、拷贝构造、拷贝赋值、移动构造、移动拷贝、析构;
	操作符函数  == > , & && * -* ->* new delete

【default】:C++11提供该关键字显示指定为默认版本;
【deleted】:C++11提供该关键字显示指定为删除该函数;  

- 此类函数能够用于类外的成员函数上;
- 也可以使用类上;
- deleted可以删除一些转换函数,防止隐式转换;如:operator(char c) = deleted;
- 也可以使用在普通函数上;

3、lambda函数

lambda:该函数是基于初始状态进行运算(闭包的类),也就是一个函数对象;
表达式为:[捕捉外部变量](形参列表)mutable -> return-type { ...}
- []:捕捉列表,类似于类中的构造函数;
	- [var]:以值传递,若加上`&`则表示引用传递;
	- this:以值传递一个this指针;
	- [=]:传值的方式捕获外部所有变量;
	- [&]:引用的方式捕获外部所以变量;
	- 传入多个使用`,`分割;
	- 捕捉列表不允许变量重复传递,当可以通过不同方式传递相同变量;
	- 
- ():参数列表,若无参数,则可以省略;
- mutable:默认为const,使用该修饰符可以取消常量性,当使用该修饰符,则()不能省略;
- ->return-type:返回类型;
- {}:函数体;

【使用场景】:
- 智能指针的删除器:如引用一个文件,需要关闭文件;
3.1 lambda与仿函数

C++【STL】 | 仿函数的应用以及如何规范要求

可以使用lambda替代仿函数;
class AirportPrice {
private:
	float _dutyfreerate;
public:
	AirportPrice(float rate) : _dutyfreerate(rate) {}
	float operator(float price) {
		return price * (1-_dutyfreerate/100);
	}
};

void test() {
	float tax_rate = 5.5f;
	AirportPrice Changi(tax_rate);
	auto Changi2 = [tax_rate](float price)->float{return price * (1-tax-rate/100);};
	/**
	[tax_rate]相当于类构造;
	(float price)->float{return price * (1-tax-rate/100);}相当于float operator(float price)
	*/ 
	float purchased = Changi(3699);
	float purchased = Changi2(2899);
}
3.2 lambad的参数问题
【值传递】:传递的值在`函数定义`时的值;
【引用传递】:传递的值是`函数调用`时(运行时)的值;
void test() {
    int j = 12;
    auto by_val = [=] { return j+1; };
    auto by_ref = [&]{return j+1;};

    cout << "by_val " << by_val() << endl;
    cout << "by_ref " << by_ref() << endl;

    j++;
    cout << "by_val " << by_val() << endl;
    cout << "by_ref " << by_ref() << endl;
}
/**
		by_val 13
		by_ref 13
		by_val 13
		by_ref 14
*/
C++11允许lambda向函数指针的转换;
- 该函数不能捕捉任何变量;
- 该函数类型需要一致;
- 参数必须一致;

mutable和const

【值传递】:const下,不能修改常量,mutable下可以,但修改不了外部变量;
【引用传递】:const下能修改但该不了外部变量,mutable可以将该外部变量修改;
void test() {
    int j = 12;
    auto by_val = [=] { return j+1; };
    auto by_ref = [&]{ j = 10; return j;};

    cout << "by_val " << by_val() << endl;      // 13
    cout << j << endl;                          // 12
    cout << "by_ref " << by_ref() << endl;      // 10 引用被lambda修改
    cout << j << endl;                          // 10 引用被lambda修改

    auto by_val_1 = [=]()mutable {  j = 1; return j; };
    auto by_ref_1 = [&] ()mutable { j = 2; return j; };

    cout << "by_val " << by_val_1() << endl;    // 1 被lambda修改为1
    cout << j << endl;                          // 10 没有被lambda改变   
    cout << "by_ref " << by_ref_1() << endl;    // 2 被lambda修改为2
    cout << j << endl;                          // 2 被lambda改变
}
3.3 lambda与STL
可以将lambda应用于STL函数,提高代码的可读性,正确性,可维护性且其性能与内联函数不存在大的差别;
如:
find_if(begin(), end(), compose2(logical_and<bool>(),
						bind2nd(less<int>(), high),
						bind2nd(greater_equal<int>(), low)));
find_if(begin(), end(), [=](int i){
		return i >= low && i < high;
	});
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jxiepc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值