1.使用迭代器去遍历容器,而不管迭代器底层数据的类型。
2.c++STL。
STL包含了、容器,空间配置器、泛型算法、类型萃取。memcpy内存拷贝,二倍扩容。
insert
esreas
3.泛型算法:模板实现。只注重方法,不在乎类型。
泛型算法就是操作容器、迭代器的。
给迭代器提供,中括号运算符重载函数。直接通过下标访问元素。
泛型算法,只用迭代器。
typename 不仅可以定义类型,还可以告诉编译器,后面是类型。
写容器要注意:通用!!
听懂了,说不出来,跟不会一样。
提供排序的泛型算法,提供用户提供的自定义排序算法。
回调函数。
定义函数指针。template
看迭代器迭代的容器里是什么类型。
所谓所谓事件驱动就是回调函数,
事件驱动就是在事件发生之前就将事件的处理罗列出来。例如:
明天吃什么,我并不知道。但是我知道,不管我吃什么,我都会先拿一双筷子,搬个凳子,坐到那块。。。
不管吃什么,只要执行吃的操作都会固定执行这些操作。这就叫做事件驱动。
函数模板,
#include
#include
#include
#include
using std::cout;
using std::endl;template
class myallocator
{
public:// construct构造 destroy析构// allocate开辟内存 deallocate释放内存void construct(void *ptr, const T &val){new (ptr) T(val); //表示在ptr指向的内存,构造一个值为val的对象}void destroy(T *ptr){//自己填ptr->~T();}//开辟内存T* allocate(size_t size){//mallocreturn (T*)malloc(size);}//释放内存void deallocate(void *ptr){free(ptr);}
};template>
class Vector
{
public:typedef Vector _MyT;//默认构造的vector,底层没分配过内存0Vector() :mpVec(NULL), mSize(0), mCur(0){}//size表示初始的内存大小,val表示内存初始值Vector(int size, const T &val = T()):mSize(size), mCur(size){mpVec = _allocator.allocate(mSize * sizeof(T));for (int i = 0; i & operator=(const Vector &src){if (this == &src)return *this;for (int i = 0; i private:T *mpVec;int mSize;int mCur;Allocator _allocator;
};//函数模板,统一进行容器元素的遍历输出
template
void showContainer(Container &con)
{Container::iterator it &#61; con.begin();for (; it !&#61; con.end(); &#43;&#43;it){cout <<*it <<" ";}cout <}
//对first和last迭代器区间的所有元素&#xff0c;进行排序&#xff0c;默认小到大
/*
1.mysort这样的函数&#xff0c;参数都接收的是迭代器&#xff0c;这一类函数在C&#43;&#43; STL
里面&#xff0c;大概有70多种&#xff0c;它们统一叫什么名字&#xff1f;
2.把mysort代码写完&#xff0c;里面不能出现具体的类型&#xff08;int&#xff0c;vector&#xff09;
3.C&#43;&#43; STL里面也有一个&#xff08;&#xff09;叫做sort&#xff0c;它当然是用快排&#xff08;递归实现&#xff09;
1亿个整数处理的时候&#xff0c;如果sort只采用递归的快排&#xff0c;那么很可能出现栈溢出问题&#xff0c;
为了处理栈溢出的问题&#xff0c;sort做了哪些处理&#xff1f;
*/
template
void mysort(IteratorT first, IteratorT last)
{int size &#61; last - first; for (int i &#61; 0; i first[j&#43;1]){IteratorT::value_type tmp &#61; first[j];first[j] &#61; first[j &#43; 1];first[j &#43; 1] &#61; tmp;}}}
}
//重载的泛型算法mysort&#xff0c;提供用户自定义的排序方式
/*
请自行提供两个函数模板&#xff0c;分别比较数据的>和<&#xff0c;并且在main函数中调用一下
该mysort重载版本&#xff0c;分别对容器的元素进行小到大&#xff0c;大到小的排序并且打印出来
事件驱动&#xff1a;逆置了事件的处理和事件发生的时间
*/
template
bool greaterFunc(T a, T b)
{return a > b;
}template
void mysort(IteratorT first, IteratorT last,FUNC pfunc)
{int size &#61; last - first;for (int i &#61; 0; i }int main(int argc, char* argv[])
{Vector vec1;srand(time(0));for (int i &#61; 0; i <20; &#43;&#43;i){vec1.push_back(rand() % 100);}showContainer(vec1);//默认从小到大排序 vector::iterator list::iteartormysort(vec1.begin(), vec1.end());showContainer(vec1);//大到小排mysort(vec1.begin(), vec1.end(), greaterFunc);//打印输出showContainer(vec1);//小到大牌//打印输出/*需要一种通用的方式&#xff0c;来遍历任何的容器 operator[]做不到的通用&#xff1a; 怎么通用&#xff1f;是使用方式通用呢&#xff1f;还是所有容器共用一个迭代器呢&#xff1f;数组operator[]链表二维数组哈希表红黑树迭代器和容器是一一对应的&#xff0c;所以在设计上&#xff0c;把迭代器这个类&#xff0c;设计成容器类型的嵌套类性*//*1.需要在容器里面定义嵌套类型 iterator2.给容器提供begin方法 iterator begin(); 把容器第0号位元素的迭代器返回回去3.给容器提供end方法 iterator end(); 把容器末尾元素后继位置的迭代器返回回去4.给迭代器提供operator!&#61;5.给迭代器提供operator&#43;&#43;()6.给迭代器提供operator*()Vector::iterator it &#61; vec1.begin();for (; it !&#61; vec1.end(); &#43;&#43;it){cout <<*it <<" ";}cout <::iterator it &#61; vec1.begin();for (; it !&#61; vec1.end(); &#43;&#43;it){if (*it % 2 &#61;&#61; 0){// it.operator*()*it &#61; 0; //error C2106 : “ &#61; ” : 左操作数必须为左值}}showContainer(vec1);string str1 &#61; "hello world";string::iterator it2 &#61; str1.begin();for (; it2 !&#61; str1.end(); &#43;&#43;it2){cout <<*it2;}cout <}
函数不能进行内联&#xff0c;因为在编译时&#xff0c;只通过函数指针并不能确定调用的是哪个函数。
效率太低&#xff0c;无法内联。哪怕函数指针指向的是内联函数&#xff0c;也不能做内联处理。
在c&#43;&#43;中使用函数指针存在的两个问题。
1.效率太低&#xff0c;无法内联。
2.函数函数局部作用域。无法对这些信息进行封装和隐藏。
事件驱动&#xff1a;在事件还没发生之前就将事件发生后需要执行的方法定义好了&#xff0c;只要事件发生了就执行相应的函数方法。
解决&#xff1a;目标
我要能够内联。
类的名字首字母大写。
小括号又叫函数调用运算符。
主要用在泛型算法中&#xff0c;扩展泛型算法功能。
因为提供了对象的圆括号运算符重载函数。所以它直接调用的是对象的圆括号运算符重载函数。
那都不差&#xff0c;就差在学习方法上。
不能死记硬背&#xff0c;死记硬背在面试官面前连一程都撑不下来。
泛型算法主要针对容器。
排序&#xff0c;对函数功能进行扩展。
方法有问题。
改个类型名字。
传引用进来&#xff0c;避免了临时对象的构造和析构。