植物大战仿函数——C++
- 软件开发
- 2025-08-19 18:33:03

容器适配器
容器适配器不支持迭代器。栈这个东西,让你随便去遍历,是不好的。他是遵循后进先出的。所以他提供了一个街头top取得栈顶数据。
仿函数仿函数(functor)是C++中一种重载了函数调用运算符(operator())的类或结构体,它可以像函数一样被调用。仿函数是一种通用的编程技巧,它可以使某些算法的行为变得更加灵活。
在C++中,STL(标准模板库)中的许多算法都接受一个仿函数作为参数,例如 std::sort() 和 std::for_each()。当这些算法被调用时,它们使用传递的仿函数来决定如何对元素进行操作,从而使算法的行为能够被用户所控制。
仿函数 或者叫函数对象,可以像函数一样使用 搞成模板可以支持各种类型
// template<class T> struct less { bool operator()(const T& x, const T& y) const { return x < y; } }; template<class T> struct greater { bool operator()(const T& x, const T& y) const { return x > y; } }; template<class T, class Container = vector<T>, class Compare = less<T>> class priority_queue { public: //大堆用 < Compare comFunc; void AdjustUp(int child) { int parent = (child - 1) / 2; while (child > 0) { if (comFunc(_con[parent], _con[child])) { swap(_con[parent], _con[child]); child = parent; parent = (child - 1) / 2; } else { break; } } }仿函数在用的时候简单的不需要我们写,在的库里包含着。
我们用的时候只需要包含头文件即可。
以上仿函数的基础用法
仿函数的优势可以在很多场景用来替代函数指针。
C语言的函数指针非常麻烦,一般不用,但是c++需要去兼容C语言。
对于以上仿函数的写法,也可以用c语言的函数指针来写。
因为有了模板,所以c++不仅对自定义类型支持构造函数,也对内置类型支持,int就是0,double就是0.0,指针就是空指针
sort函数sort是一个函数模板。
sort传参穿的是一个函数对象。
这和priority的优先级队列不同,优先级队列传递的模板类型。
所以sort用匿名对象来构造对象即可。
vector<int> v; sort(v.begin(), v.end(),greater<int>()); 对于排序的自定义类型可以自己写仿函数,代码如下。
struct LessPrice { bool operator<(const Goods& g1, const Goods& g2) const { return g1._price < g2._price; } }; deque 对于vector优点:适合尾插尾删,随机访问**(最强)**
缺点: 1.不适合头部或者中部插入删除,效率低,需要挪动数据 2.扩容有一定性能消耗,还存在一定程度的空间浪费。因为它删除数据不缩容
对于list优点: 1.任意位置插入删除效率高O(1)(最强) 2.按需申请释放空间
缺点: 1.不支持随机访问。(不是不支持,而是效率太低了) 2.cpu高速缓存命中率低。
对于deque(了解即可)deque是结合了以上两个容器的优缺点来设计的。
结构有点像动态开辟的二维数组。只是有点像。
deque为了控制有几个数组。设计了一个中控数组。数组里面都是指向某个数组的指针。中控数组满了,还是需要扩容,单数扩容代价低,因为只要存储指针即可。代价很低。
第一个buffer和最后一个buffer不满,中间的buffer都是满的。
优点: 1.头部和尾部插入删除数据效率不错 2.支持随机访问 3.扩容代价小 4.cpu高速缓存命中率高。
虽然以上有优点,但是看起来厉害,实际上缺点很大。
缺点: 1.中部插入删除效率不行,需要挪动数据。 2.虽然支持随机访问,但是效率相比vector而言还是有一定差距。
总结:list和vector在某方面绝对很强,已经达到了极致。但是deque是全面发展,各方面都处于中等。所以不适用。
反向迭代器反向迭代器我们通过封装适配,生成相应的反向迭代器。
和stack和queue适配器的实现差不多。
在SGI版本下,正向迭代器和反向迭代器是对称设计的。 反向迭代器适配代码
#pragma once //反向迭代器 namespace cao { // 正向迭代器 引用 指针 template<class Iterator, class Ref, class Ptr> struct Reverse_iterator { //用传过来的正向迭代器进行定义一个对象 Iterator _it; //然后typedef成Self typedef Reverse_iterator<Iterator, Ref, Ptr> Self; //构造函数构造正向迭代器对象 Reverse_iterator(Iterator it) :_it(it) {} Ref operator*() { Iterator tmp = _it; return *(--tmp); } Ptr operator->() { return &(operator*()); } Self& operator++() { --_it; return *this; } Self& operator--() { ++_it; return *this; } bool operator!=(const Self& s) { return _it != s._it; } }; }list.h里面,list类的代码
template<class T> class list { typedef list_node<T> Node; public: typedef _list_iterator<T, T&, T*> iterator; typedef _list_iterator<T, const T&, const T*> const_iterator; //适配支持反向迭代器 typedef Reverse_iterator<iterator, T&, T*> reverse_iterator; typedef Reverse_iterator<const_iterator, const T&, const T*> const_reverse_iterator; reverse_iterator rbegin() { //用正向迭代器的end()迭代器构造反向迭代器的rbegin() return reverse_iterator(end()); } reverse_iterator rend() { return reverse_iterator(begin()); } const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } ................... }植物大战仿函数——C++由讯客互联软件开发栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“植物大战仿函数——C++”
下一篇
一文带你吃透操作系统