从栈的接口中可以看出,栈实际是一种特殊的vector,因此使用vector完全可以模拟实现stack。
#include
#include
using namespace std;
int main()
{return 0;
}
namespace ait
{templateclass stack{public:stack() {}void push(const T& x) { _c.push_back(x); }void pop() { _c.pop_back(); }T& top() { return _c.back(); }const T& top()const { return _c.back(); }size_t size()const { return _c.size(); }bool empty()const { return _c.empty(); }private:std::vector _c;};
}
#include
namespace bite
{templateclass queue{public:queue() {}void push(const T& x) {_c.push_back(x);}void pop() {_c.pop_front();}T& back() {return _c.back();}const T& back()const {return _c.back();}T& front() {return _c.front();}const T& front()const {return _c.front();}size_t size()const {return _c.size();}bool empty()const {return _c.empty();}private:std::list _c;};
}
适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结),该种模式是将一个类的接口转换成客户希望的另外一个接口。
设计模式:
适配器模式:已有的东西转换出你想要的东西
迭代器模式:不暴露底层细节,封装后提供统一的方式访问容器
STL标准库中stack和queue的底层结构:
虽然stack和queue中也可以存放元素,但在STL中并没有将其划分在容器的行列,而是将其称为容器适配
器,这是因为stack和队列只是对其他容器的接口进行了包装,STL中stack和queue默认使用deque
优先级队列默认使用vector作为其底层存储数据的容器,在vector上又使用了堆算法将vector中元素构造成
堆的结构,因此priority_queue就是堆,所有需要用到堆的位置,都可以考虑使用priority_queue。
注意:默认情况下priority_queue是大堆。
#include
using namespace std;
#include
#include
#include
#include"Stack.h"
#include"Queue.h"
int main()
{//priority_queue pq;//默认大堆priority_queue, greater> pq;//小堆pq.push(1);pq.push(2);pq.push(3);pq.push(4);pq.push(5);while (!pq.empty()){cout << pq.top() << " ";pq.pop();}cout << endl;system("pause");return 0;
}
含义:是C++标准库中的一个头文件,定义了C++标准中多个用于表示函数对象(function object)的类模板,包括算法操作、比较操作、逻辑操作;以及用于绑定函数对象的实参值的绑定器(binder)。这些类模板的实例是具有函数调用运算符(function call operator)的C++类,这些类的实例可以如同函数一样调用。不必写新的函数对象,而仅是组合预定义的函数对象与函数对象适配器(function object adaptor),就可以执行非常复杂的操作。
含义:
函数指针的调用,即是一个通过函数指针调用的函数;如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,就说这是回调函数。
作用:
“解耦”,普通函数代替不了回调函数的这个特点。这是回调函数最大的特点
具体用法:
解耦:在主入口程序中,把回调函数像参数一样传入库函数。这样一来,只要我们改变传进库函数的参数,就可以实现不同的功能,且不需要修改库函数的实现,变的很灵活,这就是解耦。
使用:如果库函数对我们不可见,我们修改不了库函数的实现,也就是说不能通过修改库函数让库函数调用普通函数那样实现,那我们就只能通过传入不同的回调函数了
我们都知道,函数的入参除了是普通变量之外,还可以是函数指针(C 语言中就经常这么用)。那有没有什么手段能代替函数指针呢?
定义一个类,类里面定义了某个方法,将该类的对象作为函数的入参,那么在函数中就能调用这个类中的方法;定义一个类,类里面重载函数运算符(),将该类的对象作为函数的入参,那么在函数中同样能调用重载符()里面的方法,因此,仿函数就是仿造的函数,它并不是一个真正意义上的函数。它是一个类中的运算符()重载,但它具有函数的功能。
#include class Compare {
private:int m_Number;
public:Compare(int num) : m_Number(num){}bool operator()(int other){return m_Number > other;}};int main()
{Compare cmp(10);std::cout << cmp(11) << std::endl;std::cout << cmp(9) << std::endl;std::cin.get();return 0;
}
仿函数的优点:
函数对象的出现是为了代替函数指针的,最明显的一个特点是:可以使用内联函数。而如果使用内联函数的指针,编译器会把它当普通函数对待。另外,函数对象是类封装的,代码不但看起来简洁,设计也灵活,比如还可以用关联,聚合,依赖的类之间的关系,与用到他们的类组合在一起,这样有利于资源的管理,说到这,大家是不是对仿函数有了很清晰的认识了。每个新事物的诞生都有它的原因,我们更应该去关注这个新事物出现的原因,而不仅仅是它本身。
上一篇:运维自动化之Ansible