C++11Lambda表达式|智能指针

Lambda表达式:

定义:

        可以理解为一个匿名函数。和函数一样,lambda表达式具有一个返回类型、一个参数列表和一个函数体。

语法:[capture list] (parameter list) -> return type {function body}

capture list:表示捕获列表,捕获的是lambda所在函数中定义的局部变量
parameter list:表示参数列表
return type:返回类型
function body:函数体

捕获列表:

1.  auto func = [](int a) {return a; };//捕获列表为空,即什么都不捕获

2.  int b=10;

     auto func = [b]() {return b; };//值捕获,仅获取值,不获取指针

3   int b=10;

     auto func = [&b]() { b=99;return b; };//引用捕获,获取值,获取指针(可修改值),调用func()后,b变为99。

---------------------------------------------------------------------------------------------------

4  int i = 10;
    int j = 20;
    int k = 30;

    auto test1 = [=]() { cout <<"i为:"<< i << endl <<"j为:" << j << endl<< "k为:" << k << endl; };// 捕获列表中的”=“表示,获取Lambda表达式所在函数体内的所有局部变量,叫默认值捕获,仅可获取值,不获取指针

5  int i = 10;
    int j = 20;
    int k = 30;

    auto test3 = [&]() { i=k=j = 999; cout << "i为:" << i << endl << "j为:" << j << endl << "k为:" << k << endl; };// i,j和k的值都被修改为999,因为捕获列表中的"="表示获取Lambda表达式所在函数体内所有局部变量的引用,叫默认引用捕获。获取指针和值,可修改值。

代码实现验证:

#include<iostream>
using namespace std;
int main()
{
	int i = 10;
	int j = 20;
	int k = 30;
	auto func = [](int a) {return a; };
	cout << "func为:" << func(10) << endl;

	auto max = [](int a, int b) {if (a > b) { return a; } else return b; };
	cout << endl<< "max为:" << max(4, 44) << endl;

	auto test1 = [=]() { cout <<"i为:"<< i << endl <<"j为:" << j << endl<< "k为:" << k << endl; };
	auto test2 = [=, &i]() { i = 99; cout << "i为:" << i << endl << "j为:" << j << endl << "k为:" << k << endl; };
	auto test3 = [&, i]() { k=j = 999; cout << "i为:" << i << endl << "j为:" << j << endl << "k为:" << k << endl; };

	cout << endl << "test1----------------" << endl;
	test1();

	cout << endl << "test2----------------" << endl;
	test2();
	cout << "i的值为:" << i << endl;

	cout << endl << "test3----------------" << endl;
	test3();
	cout << "i的值为:" << i << endl;

	return 0;
}

测试:

 i的值在test2()和test3()中不一样,但是在main函数体内,调用test2()后i的值一直是99,说明了Lambda表达式在预编译阶段完成。

function及bind函数:

#include<iostream>
using namespace std;
#include<functional>

class Test
{
public:
	static int myTest(int n)
	{
		return n;
	}

	int operator()(int n)
	{
		return n;
	}
};
int test(int n)
{
	return n;
}
void foo(int a,int b, int c)
{
	cout << a << b << c << endl << endl;
}
int main() 
{
	//函数对象包装器
	//为函数提供容器(即封装)

	//支持四种函数
	//1.普通函数
	function<int(int)> f1= test;
	cout << "f1=" << f1(100) << endl;

	auto f2 = test;
	cout << "f2=" << f2(200) << endl;;

	//2.匿名函数
	function<int(int)> f3 = [](int n)->int {return n; };
	cout << "f3=" << f3(300) << endl;

	function<int(int)> f4 = [](int n) {return n; };
	cout << "f4=" << f4(400) << endl;

	//3.成员函数
	function<int(int)> f5 =Test::myTest;
	//auto f5 = &Test::myTest;
	Test t1;
	cout << "f5=" << f5(500) << endl;


	//4.仿函数
	function<int(Test*, int)> f6 = &Test::operator();
	cout << "f6=" << f6(&t1, 600) << endl;

	auto f7=bind(foo, 10, 20, 30);
	f7();

	auto f8 = bind(foo, 10, placeholders::_1, 30);
	f8(20);

	auto f9 = bind(foo, placeholders::_2, placeholders::_1, 30);
	f9(10,20);
	return 0;
}

   auto f9 = bind(foo, 10, placeholders::_1, 30);

   //error! 因为第一个参数还没使用就使用第二个参数了
   f9(20);//error! 

测试:

智能指针:

unique_ptr:

        有且仅有一个,不能拷贝,不能赋值。假设两个引用指向同一个指针,如果一个引用销毁了该指针,那么另一个引用则为空,会导致内存泄露,因此编译器不让unique指针进行赋值或拷贝操作。

unique_ptr<Test> t1 = make_unique<Test>();

unique_ptr<Test> t1(new Test());// 可能会出现异常安全问题

unique_ptr<Test> t2 = t1;//error!

 shared_ptr:

        该指针可共享,(都为共享指针时)赋值或拷贝一次会增加引用数,当引用数为零时,内存释放。什么情况下,引用减少呢?就是共享指针脱离作用域时减少一次引用数。

shared_ptr<Test> t2 = make_shared<Test>();//进行一次内存分配

shared_ptr<Test> t3 (new Test());//会进行两次内存分配,new了后再拷贝,共两次。

shared_ptr<Test> t4;

t4=t3;//引用数+1。

 weak_ptr:

        目的是为配合 shared_ptr 而引入的一种智能指针来协助 shared_ptr 工作, 它只可以从一个 shared_ptr 或另一个 weak_ptr 对象构造不会增加共享指针的引用数,也是在作用域内生存,脱离生存期立即死亡。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++智能指针 ⼀ ⼀. 智能指针 智能指针C++ 中,我们申请内存⼀般使⽤ new,释放内存时使⽤ delete,但是有时候我们可能由于疏忽会忘记 delete,或者当程序有多个 出⼝时,也会容易有 new 没有 delete,这样就产⽣了内存泄漏,如果你的程序是⼀个需要长期运⾏的服务器程序,可能运⾏着⼏天突然程 序就崩溃了,原因也不好定位,所以为了⽅便内存管理,C++ 引⼊了智能指针智能指针的优点在于能够帮助程序员⾃动释放我们 new 出 来的堆内存。 C++ 标准库有四种智能指针:auto_ptr,unique_ptr,shared_ptr,weak_ptr(auto_ptr 是 C++98 标准的,其余都是 C++11 标准推出的,auto_ptr 现在已经不再使⽤了),C++11 这三种智能指针都是类模板。 ⼆ ⼆. shared_ptr (⼀)概述 (⼀)概述 shared_ptr 是⼀个共享式指针,所有的 shared_ptr 共享对指向内存的所有权,不是被⼀个 shared_ptr 拥有,⽽是多个 shared_ptr 之间互相协作。 (⼆)⼯作原理 (⼆)⼯作原理 引⽤计数,use_count 为 0 时就释放对象空间。 (三)初始化 (三)初始化 如果是定义了⼀个智能指针却不初始化,shared_ptr<int> p1,代表定义了⼀个指向 int 类型对象的智能指针但是⽬前指向为 empty。推荐使⽤ make_shared 函数来初始化 shared_ptr,它是标准库的函数模板,安全,⾼效地分配和使⽤ shared_ptr。 shared_ptr<int> pint = make_shared<int>(100); shared_ptr<string> pstr = make_shared<string>(5,'a'); 也可以使⽤直接初始化的⽅式 shared_ptr<int> pint(new int(100)) 来创建⼀个 shared_ptr 并初始化,但是由于 shared_ptr 定义 的构造函数是 explicit 的,因此不能使⽤ shared_ptr<int> pint = new int(100) 来创建⼀个 shared_ptr 并初始化,因为这种⽅式隐式要 求将⼀个普通的 int * 转换为 shared_ptr<int>。 (四)常⽤操作 (四)常⽤操作 1. use_count 返回多少个智能指针指向该对象,主要⽤于调试。 2. unique 判断该智能指针是否独占该内存,如果该智能指针不指向任何对象,判断 unique 的时候也是假。 3. reset 不带参数时:放弃指针对对象的掌管权,重置为 nullptr 带参数时:参数⼀般是⼀个 new 的空间,相当于放弃指针对当前对象的掌管权,然后将指针指向 new 出来的空间。 4. * 解引⽤,可以获取指针指向的对象。 5. get 获取指针指针⾥保存的裸指针,⼀般⽤于⼀些接⼝需要使⽤到 C 语⾔指针的情况。 6. swap 交换两个智能指针所指的对象。 7. =nullptr 该智能指针指向 nullptr,代表解除对该对象的掌握权,引⽤计数将会减1,如果此时该内存空间的引⽤计数变为0,会同时释放该内存。 8. 指定删除器以及删除数组问题 指定删除器以及删除数组问题 智能指针能在⼀定时机帮我们删除所指向的对象,使⽤ delete 作为默认的资源析构⽅式,我们也可以指定⾃⼰的删除器取代系统提供的默 认删除器,当智能指针需要删除所指向的对象时,编译器就会调⽤我们提供的删除器。 shared_ptr 指定删除器的⽅法⽐较简单,⼀般只需要在参数中添加具体的删除器函数即可。如果提供了删除器,那么就需要⼿动删除资 源,否则会造成内存泄漏。删除器函数可以是函数,lambda 表达式,重载了 operator() 的类等。 还可以使⽤ default_delete 来做删除器,default_delete 是标准库⾥的⼀个模板类。如:shared_ptr<A> p3(new A[10], default_delete<A[]>()),这样就知道我们使⽤智能指针指向了⼀个对象数组,这样就可以正确释放了。 其实,使⽤ shared_ptr 指向对象数组不需要通过删除器的⽅式,只需要在定义 shared_ptr 时指为数组类型即可,如:shared_ptr<A[]> p4(new A[10])。 额外说明:就算是两个 shared_ptr 指定了不同的删除器,只要他们指向的对象类型相同,那么这两个 shared_ptr 也是同⼀个类型,可以 放到同⼀个容器去,vector<shared_ptr<int>> pvec{p1,p2}。 三 三
C++ Primer中文版(第5版)[203M]分3个压缩包 本书是久负盛名的C++经典教程,其内容是C++大师Stanley B. Lippman丰富的实践经验和C++标准委员会原负责人Josée Lajoie对C++标准深入理解的完美结合,已经帮助全球无数程序员学会了C++。 对C++基本概念和技术全面而且权威的阐述,对现代C++编程风格的强调,使本书成为C++初学者的最佳指南;对于中高级程序员,本书也是不可或缺的参考书。 目录 第1章 开始 1   1.1 编写一个简单的C++程序 2   1.1.1 编译、运行程序 3   1.2 初识输入输出 5   1.3 注释简介 8   1.4 控制流 10   1.4.1 while语句 10   1.4.2 for语句 11   1.4.3 读取数量不定的输入数据 13   1.4.4 if语句 15   1.5 类简介 17   1.5.1 Sales_item类 17   1.5.2 初识成员函数 20   1.6 书店程序 21   小结 23   术语表 23   第Ⅰ部分 C++基础 27   第2章 变量和基本类型 29   2.1 基本内置类型 30   2.1.1 算术类型 30   2.1.2 类型转换 32   2.1.3 字面值常量 35   2.2 变量 38   2.2.1 变量定义 38   2.2.2 变量声明和定义的关系 41   2.2.3 标识符 42   2.2.4 名字的作用域 43   2.3 复合类型 45   2.3.1 引用 45   2.3.2 指针 47   2.3.3 理解复合类型的声明 51   2.4 const限定符 53   2.4.1 const的引用 54   2.4.2 指针和const 56   2.4.3 顶层const 57   2.4.4 constexpr和常量表达式 58   2.5 处理类型 60   2.5.1 类型别名 60   2.5.2 auto类型说明符 61   2.5.3 decltype类型指示符 62   2.6 自定义数据结构 64   2.6.1 定义Sales_data类型 64   2.6.2 使用Sales_data类 66   2.6.3 编写自己的头文件 67   小结 69   术语表 69   第3章 字符串、向量和数组 73   3.1 命名空间的using声明 74   3.2 标准库类型string 75   3.2.1 定义和初始化string对象 76   3.2.2 string对象上的操作 77   3.2.3 处理string对象中的字符 81   3.3 标准库类型vector 86   3.3.1 定义和初始化vector对象 87   3.3.2 向vector对象中添加元素 90   3.3.3 其他vector操作 91   3.4 迭代器介绍 95   3.4.1 使用迭代器 95   3.4.2 迭代器运算 99   3.5 数组 101   3.5.1 定义和初始化内置数组 101   3.5.2 访问数组元素 103   3.5.3 指针和数组 105   3.5.4 C风格字符串 109   3.5.5 与旧代码的接口 111   3.6 多维数组 112   小结 117   术语表 117   第4章 表达式 119   4.1 基础 120   4.1.1 基本概念 120   4.1.2 优先级与结合律 121   4.1.3 求值顺序 123   4.2 算术运算符 124   4.3 逻辑和关系运算符 126   4.4 赋值运算符 129   4.5 递增和递减运算符 131   4.6 成员访问运算符 133   4.7 条件运算符 134   4.8 位运算符 135   4.9 sizeof运算符 139   4.10 逗号运算符 140   4.11 类型转换 141   4.11.1 算术转换 142   4.11.2 其他隐式类型转换 143   4.11.3 显式转换 144   4.12 运算符优先级表 147   小结 149   术语表 149   第5章 语句 153   5.1 简单语句 154   5.2 语句作用域 155   5.3 条件语句 156   5.3.1 if语句 156   5.3.2 switch语句 159   5.4 迭代语句 165   5.4.1 while语句 165   5.4.2 传统的for语句 166   5.4.3 范围for语句 168   5.4.4 do while语句 169   5.5 跳转语句 170   5.5.1 break

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值