C++学习摘要7
来源:互联网 发布:爬虫数据采集解决方案 编辑:程序博客网 时间:2024/05/23 13:11
第17章 模板与类型转换
- 模板的定义及目的
将一种数据类型定义为参数,然后将不同数据类型按照实参形式传送而实现代码重用(类似与java的泛型机制),减少由于类型不同而产生的无所谓的重载。 - 模板的定义及使用
#include<iostream>using std::cout;using std::endl; template<class T>T min(T x,T y){ return (x<y)?x:y;} int main(){ int n1 = 2,n2 = 10; double d1 = 1.5,d2 = 5.6; //隐式调用 cout<<"较小的整数"<<min(n1,n2)<<endl; //显示调用 cout<<"较小的实数"<<min<double>(d1,d2)<<endl; return 0;}
- 模版的特殊化,模板中有一个具体实现
#include<iostream>using namespace std;template<class T>class Pair{ T value1,value2; public : Pair(T first,T second){ value1 = first; value2 = second; } T module(){ return 0; }};template<>class Pair<int>{ int value1,value2; public: Pair(int first,int second){ value1 = first; value2 = second; } int module(){ return value1%value2; }};int main(){ Pair<int> myints(100,75); Pair<float>myfloats(100.0,75.0); cout<<myints.module()<<endl; cout<<myfloats.module()<<endl; return 0;}
重载和函数模版
函数模板重载的参数匹配规则如下:
1.寻找和使用最符合函数名和参数类型的涵数。
2.寻找一个函数模版,将其实例化产生一个匹配的函数。
3.寻找可以通过类型转换的参数匹配的重载函数。
4.如果未找到则调用错误,如果找到的多于一个匹配则出现二义性。运行时类型识别
在C++中类型识别是指只有一个指向基类的指针或引用时,确定一个对象的准确类型。派生类的特殊性可以通过定义虚函数加以体现,运行时类型检查只有在必要时才使用(影响效率).两种使用方法:1.运行时识别类型typeid
shape *sh1 = new circle; cout<<typeid(*sh1).name()<<endl;
2.运行时类型强制转换dynamic_cast
#include<iostream>#include<typeinfo>using namespace std;class shape{ int s1; int s2; int s3; public: virtual void draw(); };void shape::draw(){ cout<<"shape drawing "<<endl;}class circle:public shape{ int t1; int t2; int t3; public : void draw();};void circle::draw(){ cout<<"circle drawing"<<endl;}int main(){ shape *sh1 = new circle; cout<<typeid(*sh1).name()<<endl; sh1->draw(); circle *cp = dynamic_cast<circle *>(sh1); if(cp){ cout<<"case sucessful"<<endl; cp->draw(); } return 0;}
强制类型转换运算符
1.static_cast
最常用的类型转换符,在正常状况下的类型转换,如把int转换为float,如:
int i;float f; f=(float)i;或者f=static_cast<float>(i);
2.const_cast
用于取出const属性,把const类型的指针变为非const类型的指针,如:
const int *fun(int x,int y){} int *ptr=const_cast<int *>(fun(2.3))
3.dynamic_cast
该操作符用于运行时检查该转换是否类型安全,但只在多态类型时合法,即该类至少具有一个虚拟方法。dynamic_cast与static_cast具有相同的基本语法,dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。如:
class C{ //…C没有虚拟函数};class T{ //…}int main(){ dynamic_cast<T*> (new C);//错误}此时如改为以下则是合法的:class C{public: virtual void m() {};// C现在是 多态}
4.reinterpret_cast
interpret是解释的意思,reinterpret即为重新解释,此标识符的意思即为数据的二进制形式重新解释,但是不改变其值。如:
int i; char *ptr="hello freind!"; i=reinterpret_cast<int>(ptr);这个转换方式很少使用。
第18章 容器和迭代器
- 迭代器的概念及意义
迭代器是一种检查容器内的元素并遍历元素的数据类型。 常用的迭代器
1.输入迭代器
必须能读取其所指向的值,支持的操作有*p,++p,p++,p!=q,p==q,凡是支持这五类操作的类都可以称为输入迭代器,*p只允许读取,不许修改。2.输出迭代器
必须能对指向的序列进行写操作,支持的操作同上五种
但是*p所返回的值允许修改,而不一定要读取。3.前向迭代器
支持的操作相同,但*p既可以读取也可以修改。4.双向迭代器
进一步支持操作符自减如p–,–p.5.随机存取迭代器
允许随机访问序列的任意值,如指针。迭代器类型可以使用解引用操作符(*)来访问,如*iter = 0;
- C++中的容器有顺序容器和关联容器
顺序容器
将单一容器聚集起来成为容器,然后根据位置来存储和访问数据 1.向量vector类似与java中的arraylist
主要操作有:
v.push_back();//在数组的最后一个添加一个值
v.size();//数组大小
v.empty();//判空
v[n];//返回v中位置为n的元素
v1=v2;把v1的元素替换成v2的副本
v1==v2;判断是否相等
vector进行初始化时如果没有指定元素初始化,则标准库自行提供一个初始化值进行初始化。2.双端队列
元素可以从队列的两端出队和入队,支持使用[]访问,必须引入头文件deque
主要操作有:
d.push_back(3);//从后插入
d.push_front(10);//从前插入
d.insert(1,88);//在一号位置插入,原来1号及后面的数据往后移,
d.begin();//起始位置
deque不提供容量操作,capacity(),reverse();3.列表
列表主要用于存放双向链表,可以从任意一端开始遍历,列表还提供了拼接操作,将一个序列中的元素插入到另一个序列中,需要引入头文件list
主要操作有:
l.push_back();
l.push_front();
l.erase();//删除
#include<iostream>#include<list>using namespace std;int main(){ //定义list list<int>elemets; //定义迭代器 list<int>::iterator iter; //向list中当前的指针位置插入,直到最后一位 elemets.push_back(8); elemets.push_back(5); //在当前的位置插入,直到最前一位 elemets.push_front(2); //进行迭代遍历 for(iter = elemets.begin();iter != elemets.end();iter++){ cout<<"元素:"<<*iter<<endl; } cout<<"删除元素首位后"<<endl; //删除list首位 elemets.erase(elemets.begin()); //进行迭代遍历 for(iter = elemets.begin();iter!=elemets.end();iter++){ cout<<"元素:"<<*iter<<endl; } return 0;}
- 关联容器
通过键值存取数据的集合。关联容器的读取和存储和数据写入的顺序无关,只根据键值来指定对应的元素。
- 1.集合和多集
一个集合是一个容器,所包含的元素是唯一的(set)。集合的元素按一定的顺序排列(平衡二叉树),并被作为集合中的实例。通过链表实现。如果要修改集或多级容器中的元素值,必须先删除原有的元素,在插入新元素。
集合和多集的区别:
集(set)支持唯一键,集中的值都是特定的,并且只出现一次。而多集(multiset)中可以出现副本键,一个值可以出现多次。
#include<iostream>#include<set>using namespace std;int main(){ set<int>set1; for(int i=0;i<10;i++){ set1.insert(i); } for(set<int>::iterator p=set1.begin();p!=set1.end();++p){ cout<<*p<<""; } cout<<endl; if(set1.insert(3).second){ cout<<"插入成功"<<endl; }else{ cout<<"插入失败"<<endl; } int a[] = {4,1,1,1,1,0,5,1,0}; multiset<int> A; A.insert(set1.begin(),set1.end()); A.insert(a,a+9); cout<<endl; for(multiset<int>::iterator p =A.begin();p!=A.end();++p){ cout<<*p<<""; } cout<<endl; return 0;}
- 2.映射和多重映射
基于某一个类型Key的键集的存在,提供对T类型数据的高效检索。映射(map)不支持副本键,多重映射(multimap)支持。键的本身是不能被修改的,除非删除。
集合和映射的区别:集合的键和值是key类型的,而map键和值是一个pair结构中的两个分量.
#include<iostream>#include<map>using namespace std;int main(){ // 键 值 排序方式 map<char,int,less<char> >map1; map<char,int,less<char> >::iterator mapIter; map1['c']=3; map1['d']=4; map1['b']=2; map1['a']=1; for(mapIter=map1.begin();mapIter!=map1.end();++mapIter){ cout<<""<<(*mapIter).first<<":"<<(*mapIter).second; } map<char,int,less<char> >::const_iterator ptr; ptr=map1.find('d'); cout<<endl<<""<<(*ptr).first<<"键对应于值:"<<(*ptr).second; map<int,int,less<int> >map2; map2[1]=2; map2[3]=4; map<int,int,less<int> >::const_iterator ptr2; ptr2 = map2.find(1); cout<<(*ptr2).first<<"键对应值:"<<(*ptr).second; return 0;}
容器适配器
- 1.栈
常用操作:
push(x);
pop();
top();
empty();
size(); - 2.队列
常用操作:
…
front();
back();
… - 3.优先级队列
底层使用vector或deque实现,当添加元素时,按照优先顺序插入。默认情况下元素的比较是通过比较函数对象less<<>>执行.
- C学习摘要
- C语言学习摘要
- C语言学习摘要
- C++学习摘要7
- 计算机网络 学习摘要(7)
- 《C和指针》第三章学习摘要
- 《C和指针》第四章学习摘要
- 《C和指针》第五章学习摘要
- python1-7章学习摘要
- effect java 学习摘要(7)
- c摘要
- 学习摘要
- 学习摘要
- C语言入门和基本数据类型学习摘要
- 我的c学习: 数值数据类型及表示 课件摘要
- 高质量嵌入式Linux C编程学习摘要
- c初学笔记摘要
- 《Effective C++》读书摘要
- 会话跟踪技术可以通过什么技术实现
- study-12 SSH服务介绍
- OKHttp使用Post请求及实现键值对上传
- 1. Two Sum
- PHP7扩展开发之字符串处理
- C++学习摘要7
- oss mac 客户端
- easyUI之datagrid控件使用步骤
- Codeforces Round #382 (Div. 2) D. Taxes(分拆素数和)
- 测试“单例模式”的作用域是线程还是进程
- 全排列 递归方法的步骤分析
- 高效管理文件之压缩及解压缩 .bz2 文件
- codeforces 735D Taxes 哥德巴赫猜想
- Pixhawk学习笔记(5)——PX4FLOW光流传感器调试过程记录