C++ STL算法篇(三)与智能指针 day19

C++ STL算法篇(三)与智能指针 day19

生成异变算法

  • for_each:遍历
  • fill:填充
  • fill_n:n个元素为指定元素填充
  • generate:填充
  • generate_n:填充n个元素
  • transform:一元操作
#include <iostream>
#include <algorithm>
#include <vector>
#include <numeric>
int main()
{
	//1.for_each遍历容器算法----------------------------------------------------
	std::vector<int> vec{ 1,2,3,4,5,6 };
	//只要是需要传函数指针的,都可以用lambda表达式完成
	//for_each不止是遍历,可以批量处理数据,因为它在函数指针里面完成自定义操作的
	for_each(vec.begin(), vec.end(), [](int& data) {std::cout << data << " "; });
	std::cout << std::endl;
	//例如二倍容器元素并打印
	for_each(vec.begin(), vec.end(), [](int& data) {std::cout << data * 2 << " "; });
	std::cout << std::endl;

	//2.fill填充----------------------------------------------------------------
	std::vector<int>vec2(5);
	fill(vec2.begin(), vec2.end(), 21);
	for_each(vec2.begin(), vec2.end(), [](int& data) {std::cout << data << " "; });
	std::cout << std::endl;

	//3.fill_nv n个元素为指定元素填充----------------------------------------------
	fill_n(vec2.begin(), 3, 6);
	for_each(vec2.begin(), vec2.end(), [](int& data) {std::cout << data << " "; });
	std::cout << std::endl;

	//4.generate填充,需要通过函数指针去操作----------------------------------------------
	generate(vec2.begin(), vec2.end(), []() {return 77; });
	for_each(vec2.begin(), vec2.end(), [](int& data) {std::cout << data << " "; });
	std::cout << std::endl;

	//5.generate_n 填充n个元素----------------------------------------------
	generate_n(vec2.begin(), 3, []() {return 8; });
	for_each(vec2.begin(), vec2.end(), [](int& data) {std::cout << data << " "; });
	std::cout << std::endl;

	//6.transform 一元操作,传函数指针去操作
	//通过函数指针去实现自定义的操作
	std::vector<int> one{ 1,2,3,4,5 };
	std::vector<int> two(one.size());
	transform(one.begin(), one.end(), two.begin(), [](int data) {return -data; });
	copy(two.begin(), two.end(), std::ostream_iterator<int>(std::cout, " "));
	std::cout << std::endl;
	return 0;
}
  • 运行结果
    在这里插入图片描述

堆算法

  • 堆就是一段连续的内存,按照二叉树的方式研究,存在特定结构的存储方式
  • 大顶堆:父大于子
  • 小顶堆:子大于父
  • make_heap:创建堆
  • push_heap:入堆
  • pop_heap:出堆 (单纯把元素放到容器后面,手动调用相应的尾部删除函数)
  • sort_heap:堆排序
    在这里插入图片描述
#include <iostream>
#include <algorithm>
#include <vector>
#include <numeric>
int main()
{
	//默认方式就是大顶堆
	std::vector<int> data = { 2,5,6,3 };
	make_heap(data.begin(), data.end());
	for (auto v : data)
	{
		std::cout << v << " ";
	}
	std::cout << std::endl;
	//出堆
	//要调用容器的删除算法
	while (!data.empty())
	{
		pop_heap(data.begin(), data.end());
		std::cout << data.back() << " ";
		data.pop_back();
		make_heap(data.begin(), data.end());	//委托操作做一次调整
	}
	std::cout << std::endl;
	//堆排序算法
	//堆排序算法要与生成算法的排序准则必须一致
	std::vector<int> vec{ 2,5,6,3 };
	make_heap(vec.begin(), vec.end(), std::less<int>());
	sort_heap(vec.begin(), vec.end(), std::less<int>());
	for (auto v : vec)
	{
		std::cout << v << " ";
	}
	std::cout << std::endl;
	return 0;
}
  • 运行结果
    在这里插入图片描述

C++智能指针

  • 智能指针智能在内存释放,管理new出来的对象是不需要手动释放

shared_ptr:共享型指针

  • swap 交换两个智能指针管理的数据
  • reset 重新设置
  • make_shared 创建智能指针,这个函数参数由构造函数决定
#include <iostream>
#include <algorithm>
#include <vector>
#include <memory>
class student
{
public:
	student(std::string name = "", int age = 0) :name(name), age(age) {}
	std::string getName()const { return name; };
	int getAge()const { return age; };
	~student()
	{
		std::cout << "对象释放了" << std::endl;
	}
protected:
	std::string name;
	int age;
};
//可以自己写释放函数指针,也可以用lambda表达式
void FileFree(FILE*& fp)
{
	std::cout << "文件释放成功" << std::endl;
	fclose(fp);
}

void shared()
{
	std::shared_ptr<int> object(new int(123));
	if (!object)
	{
		std::cout << "初始化失败!" << std::endl;
	}
	else
	{
		//访问数据,说白了就是弱化了指针
		std::cout << *object << std::endl;
		//获取原生指针,可以用,但是不要释放,因为智能指针会自动释放
		int* pInt = object.get();
		std::cout << *pInt << std::endl;
		//可以统计有多少个指针在管理这个对象
		std::cout << "size:" << object.use_count() << std::endl;
		std::shared_ptr<int> obeject2(object);
		std::cout << "size:" << object.use_count() << std::endl;

		//swap交换两个智能指针管理的数据
		//reset重新设置
		//make_shared创建智能指针,这个函数参数由构造函数决定

		//管理自定义类型
		std::shared_ptr<student> xiaoguaPtr = std::make_shared<student>("小瓜", 21);
		std::cout << xiaoguaPtr->getName() << " " << xiaoguaPtr->getAge() << std::endl;

		//reset重新设置指针对象的数据,释放原对象,管理新对象
		xiaoguaPtr.reset(new student("大瓜", 22));
		std::cout << xiaoguaPtr->getName() << " " << xiaoguaPtr->getAge() << std::endl;
	}
	//智能指针管理特殊形式的内存,需要自己手动写释放函数(删除器)
	{
		std::cout << "---------------------------------------" << std::endl;
		std::shared_ptr<FILE> pf(fopen("1.txt", "w+"), [](FILE*& fp) {
			std::cout << "文件释放成功" << std::endl;
			fclose(fp); });
		fputs("小瓜", pf.get());
	}
	
	{
		//智能指针管理对象数组
		std::shared_ptr<student> pArr(new student[4], [](student*& p) {delete[]p; });
	}
	//一般用容器管理对象数组
	{
		std::cout << "---------------------------------------" << std::endl;
		std::vector<student*> vec;
		vec.push_back(new student);
		vec.push_back(new student);
		//手动释放内存
		for (auto v : vec)
		{
			delete v;
		}
	}
	//用智能指针管理就不需要自己手动释放内存
	std::cout << "---------------------------------------" << std::endl;
	std::vector<std::shared_ptr<student>> vec2;
	vec2.push_back(std::shared_ptr<student>(new student("小瓜", 21)));
	vec2.push_back(std::shared_ptr<student>(new student("大瓜", 22)));
	//遍历数据
	for (auto v : vec2)
	{
		std::cout << v->getName() << " " << v->getAge() << std::endl;
	}
}
int main()
{
	shared();
	return 0;
}
  • 运行结果
    在这里插入图片描述

weak_ptr:弱引用型指针

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <memory>
class B;
class A
{
public:
	A() { std::cout << "A" << std::endl; }
	~A() { std::cout << "~A" << std::endl; }
	//std::shared_ptr<B> b;
	//弱引用
	std::weak_ptr<B> b;
};

class B
{
public:
	B() { std::cout << "B" << std::endl; }
	~B() { std::cout << "~B" << std::endl; }
	//std::shared_ptr<A> a;
	//弱引用
	std::weak_ptr<A> a;
};

void weak()
{
	std::shared_ptr<A> Aobject = std::make_shared<A>();
	std::shared_ptr<B> Bobject = std::make_shared<B>();
	std::cout << Aobject.use_count() << std::endl;
	std::cout << Bobject.use_count() << std::endl;
	//形成了一个环状,称为循环引用,会导致智能指针不会释放,所以就要使用弱引用
	Aobject->b = Bobject;
	Bobject->a = Aobject;
	std::cout << Aobject.use_count() << std::endl;
	std::cout << Bobject.use_count() << std::endl;
}
void test_weak_ptr()
{
	//1.weak_ptr不能直接创建
	//std::weak_ptr<int> pint(new int);
	//只能通过shared_ptr来构建
	std::shared_ptr<int> pint(new int(21));
	std::cout << pint.use_count() << std::endl;
	//不会影响计数的改变
	std::weak_ptr<int> wint(pint);
	std::cout << wint.use_count() << std::endl;
	//2.weak_ptr访问数据: 通过调用lock访问shared_ptr对象,再去访问数据
	std::cout << *wint.lock() << std::endl;
}
int main()
{
	weak();
	std::cout << "------------------------------------" << std::endl;
	test_weak_ptr();
	return 0;
}
  • 运行结果
    在这里插入图片描述

unique_ptr:独享型指针

  • 思想:就是禁止拷贝
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <memory>

class student
{
public:
	student()
	{
		std::cout << "student" << std::endl;
	}
	~student()
	{
		std::cout << "~student" << std::endl;
	}
};
int main()
{
	std::unique_ptr<int> ptr(new int(21));
	std::cout << *ptr << std::endl;
	//独享 一个对象一个指针去管理
	//std::unique_ptr<int> ptr2(ptr); //错误 
	//ptr2 = ptr;  //错误

	//1.采用move方法转交所有权
	//管理对象交出来去了,ptr没有东西了
	std::unique_ptr<int> ptr2;
	ptr2 = move(ptr);
	std::cout << *ptr2 << std::endl;

	//2.采用reset函数结合release返回值实现
	std::unique_ptr<int> ptr3;
	ptr3.reset(ptr2.release());
	std::cout << *ptr3 << std::endl;

	{
		//删除器的写法
		//unique_ptr<"管理数据类型","函数器函数指针类型">
		using FUNC = void(*)(student*&);
		std::unique_ptr<student, FUNC> pStudent(new student[4],
			[](student*& p) {delete[] p; });

		//自动推断写法
		auto Lambad = [](student*& p) {delete[]p; };
		std::unique_ptr<student,decltype(Lambad)> pstu(new student[4],Lambad);
	}
	return 0;
}
  • 运行结果
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值