vector<int> v = {0,1,2,3,4,5,6,7,8,9,10};
int main() {
//旧方法
//迭代器
for (vector<int>::iterator it = v.begin(); it != v.end();it++)
{
cout << *it << endl;
}
//新方法
for (int i: v)
{
cout << i << endl;
}
}
有的容器有自己的sort函数。有的容器只能用全局的sort函数
sort排序,默认从小到大
自定义排序;加入自己的排序方法
bool cmp(int x, int y) {
return x > y;
}
int main() {
int a[5] = {1, 3, 4, 2, 5};
sort(a, a + 5, cmp);
for (int i = 0; i < 5; i++) cout << a[i] << ' ';
return 0;
}
泛化
template <typename type>
class _typr_ttt
{....}
特化
template <>
class _typr_ttt<int>
{....}
template <>
class _typr_ttt<double>
{....}
运算符重载
//前置版本, ++x , 规定!!传回引用!!
int& operator ++(){
this->value++;
return this->value;
}
//后置版本, x++ , 不允许传回引用,
int operator ++(int){ //重载时设置一个占位参数int即可,代表后置版本
int tmp = this->value;
this->value++;
return tmp;
}
//类模板中成员函数类外实现
template<class T1, class T2>
class Person {
public:
//成员函数类内声明
Person(T1 name, T2 age);
void showPerson();
public:
T1 m_Name;
T2 m_Age;
};
//构造函数 类外实现
template<class T1, class T2>
Person<T1, T2>::Person(T1 name, T2 age) {
this->m_Name = name;
this->m_Age = age;
}
//类外实现友元函数
//让编译器看到Person2类的声明;
template<class T1, class T2>class Person2;
//让编译器提前看到printPerson2的声明;
template<class T1, class T2>void printPerson2(Person2<T1, T2>& p);
template<class T1, class T2>
class Person2
{
//友元函数类外实现,利用空参数模板告诉编译器这是模板函数的声明;
!!!!!!!!!!!!!!!/加上<>是强制为模板函数,不加就是普通函数;
friend void printPerson2<>(Person2<T1, T2>& p);
/*
{
cout << "姓名:" << p.m_Name << " 年龄: " << p.m_Age << endl;
}
*/
public:
Person2(T1 name, T2 age)
{
this->m_Name = name;
this->m_Age = age;
}
private:
T1 m_Name;
T2 m_Age;
};
//类外实现:
template<class T1, class T2>
void printPerson2(Person2<T1, T2>& p)
{
cout << "姓名:" << p.m_Name << " 年龄: " << p.m_Age << endl;
}
void test02()
{
Person2<string, int>p1("asadasd", 10);
printPerson2(p1);
}
static成员是属于类模板具体化的类,而不是类模板本身。
template<typename T>
class A
{
static int a;
}
template<typename T> int A<T>::a=0;//类外初始化
//T为 int 或者 char 时,静态变量a是不一样的,a属于具体的类,不属于模板
cpp中rand()的使用:
总结来说,可以表示为:int num = rand() % n +a;
其中的a是起始值,n-1+a是终止值,n是整数的范围。
一般性:rand() % (b-a+1)+ a ; 就表示 a~b 之间的一个随机整数
A *pa=new A;///生成父类指针
B *pb=(B*)pa;//父类指针转成子类
//父类指针指向子类对象
Base_J *pB = new Derived_J();
delete pB;
array 定值 array<typename.size>
vector 后扩充 vector<typename>
find函数的输出是迭代器 vector<int>::iterator a=find(v.begin(),v.end(),0);
deque 前后扩充 实质是分段连续
list 双向链表 list<int> ;只能用自己的sort函数,全局sort不能使用
stack是栈 先进后出
Queue是队 先进先出
map key不能相同 map<typename, typename>
multimap key能相同
set set<typename> 插入时自动排序 数据不能相同 set<typename>
multiset 数据能相同
iterator五个必须要有的类型
template<class T,class Ref,class Ptr,...>
class __iterator
{
typedef random_access_iterator_tag iterator_category;
typedef T value_type;
typedef Ptr pointer;
typedef Ref reference;
typedef ptrdiff_t difference_type;
}
list容器(双向链表):一份数据,两根指针
1.重载i++ 和 ++i区分
i++ : self operator++(int)//调用++i
++i : self& operator++()
2.list的迭代器iterator需要单独设计成一个类,因为list需要前后指针
vector容器:单向开口 插值之后会重新开辟一块内存(两倍增长)来存放数据
1.vector的iterator不需要单独设计成类
array:
deque:双向开口 缓冲区分段存储,连续假象
1.insert时会讨论插入位置与头和尾的距离
stack和queue都是deque关闭部分功能生成的
并且都没有迭代器iterator
stack 先进后出
queue 先进先出
红黑树 rb_tree
set的key=vaule,自动排序 iterator是常指针(const iterator),不能改变元素
set里的红黑树是insert_unique 不能有重复数据
multiset里的红黑树是insert_equal 可以有重复数据
set不能用迭代器修改内容:
std::set<int> iset;
std::set<int>::iterator it = iset.insert(4).first;
(*it)++; // error. 原因:std::set的迭代器不能修改对应的元素.
set里面的元素不能直接的更改,一般的做法是先删除旧元素,然后添加新元素
map multimap底层是rb_tree,
map的value是key data组成,不会排序
用iterator不能直接改变key(因为是const key),但是可以改变data
map 里的红黑树是insert_unique 不能有重复key
multimap 里的红黑树是insert_equal 可以有重复key
map的排序默认按照key从小到大进行排序
hashtable、unordered、哈希表:一个数据、一根指针(指向下一个数据)
M是容量;编号H就放在H里面;超过容量就放在H/M的位置上;
H/M的位置上可能会存在 数据碰撞 ,发生碰撞就做成链表
separate chaining ,把同样位置的数据做成链表
大于容量后就容量增长,重新安排数据
算法 就是模板函数
template<typename T>
Algorithm(T t1,T t2)
{}
template<typename T,typename Cmp>//Cmp是准则
Algorithm(T t1,T t2,Cmp c)
{}
侯捷STL标准库和泛型编程
于 2022-07-20 21:54:13 首次发布