**1.命名空间2.字符串3.容器(STL)4.迭代器5
2016.7.5**
复习:
异常:throw(抛出异常)抛出异常后后面不会继续执行
try(捕获异常)有可能发生错误的代码放到try Block中
catch(处理异常)跟在try后边,带有一参数,可以有多个catch
…:默认(可以处理任何类型异常,不能判断出异常的 类型),一定放在catch最后
逻辑代码和判断区分
void func() throw(int , class){}
void func(){}
void func()throw(…){}
void func()throw(){}
函数模板:函数参数类型不同,实现过程相似,函数模板
template
void func(T n){}
调用函数T根据参数类型来确定自己的类型
函数和函数模板:函数(类型确定,值不确定),函数模板(类型不确定,值不确定)
类模板:类的成员变量类型不确定,每个成员函数都是函数模板。所以每个成员函数是现实需要template
注意:类名::print(){}
创建对象时未确定未实例化:
**1.namespace:命名空间,解决相同作用域同名函数或变量问题
要求:使用时必须 ’名字空间::成员名称‘**
#include <iostream>
using namespace std;
namespace yong {
int count=100;
int size=200;
namespace in{//命名空间可嵌套
int a=10;
int size=20;//两个size不会冲突
}
void print(){
cout<<count<<endl;
}
}
int main(int argc, const char * argv[]) {
cout<<yong::count<<endl;
cout<<yong::size<<endl;
cout<<yong::in::a<<endl;
cout<<yong::in::size<<endl;
yong::print();
std::cout << "Hello, World!\n";
return 0;
}
2.运行时类型识别:
类型转换:强制类型转换(向下转型)
a.动态类型转换:dynamic_cast,把父类指针转换成子类指针(如果转型成功,返回子类,如果失败返回NULL,向下转型安全)
使用格式: dynamic_cast<>(),用来检测父类指针是否可以转换成子 类指针。如果转型成功 ,返回子类,如果失败返回NULL
b.静态类型转换:static——cast和强制类型转换效果相同
动态类型转换:必须有virtual函数(多态)。
class Bace{
public:
virtual void print(){
cout<<"virtual Bace.."<<endl;
}
void outB() const{
cout<<"Bace..."<<endl;
}
};
class D1:public Bace{
public:
void print() const{
cout<<"virtual D1..."<<endl;
}
void outD1() const{
cout<<"D1.."<<endl;
}
};
class D2:public Bace{
public:
void print()const {
cout<<"virtual D2..."<<endl;
}
void outD2()const{
cout<<"D2.."<<endl;
}
};
int main(){
D1 b1;
D2 b2;
const D1*p1=NULL;
const D2*p2=NULL;
Bace* p[2]={&b1,&b2};
for(int i=0;i<2;i++)
{
if((p1=dynamic_cast<D1*>(p[i])))
{
cout<<"a"<<endl;
p1->print();
p1->outD1();
}
else if((p2=dynamic_cast<D2*>(p[i])))
{
cout<<"b"<<endl;
p2->print();
p2->outD2();
}
}
}
3.字符串
a.使用字符串初始化字符串对象
string str1(“holle~”);
cout<
#include <iostream>
using namespace std;
class Person{
private:
string name;
int age;
public:
Person(string _name,int _age){
name=_name;
age=_age;
}
void setName(string _name){
name=_name;
}
void print(){
cout<<"--------------"<<endl;
cout<<name<<endl;
cout<<age<<endl;
}
};
int main(){
//strin在类中的使用
Person p1("123",14);
Person p2("asd",16);
p1.print();
p2.print();
p1.setName("haha");
p1.print();
return 0;
}
5.容器:存储同类型数据项的一个集合(相同数据类型的一个集合)
分类:1.顺序容器。2.关联容器。
a.顺序容器:
(1) 向量Vector: 随机访问任何一个元素,尾部增、删元素。 (系统做好了下标操作符重载;头部增、删元素消耗时间和容器中元素个数成正比;尾部增删元素消耗时间是一个const)
(2) 双端对列Deque: 随机访问,在头部和尾部增删元素。(系统做好了下标操作符重载;头部尾部增删元素时间都为const。)
(3) 链表List: 顺序访问,任意位置增删元素。
b.关联容器(key:value键值对形式)
(1)集合Set: 集合存储不能有重复元素。(key和value映射到一起,(key就是value,value就是key))
(2)多集合MultiSet: 集合存储可以有重复元素。
(3)映射Map: 一对一的键值对(key,value),值可以通过指定的键检 索,其中键(key)不能重复
(4)多映射MultiMap: 一对多的键值对(key,value),其中键(key)可以重复
c.要使用容器类,包括下面的头文件(在命名空间中定义的) < deque >
#include <iostream>
#include<vector>
using namespace std;
//容器:存储同类型数据项的一个集合(相同数据类型的一个集合)
void func(){
vector<int> v;//向量
v.push_back(100);
v.push_back(200);
v.push_back(300);
v.push_back(400);
cout<<v[2]<<endl;//访问(不会给出越界提示)
cout<<v.at(2)<<endl;//访问(会给出越界提示)
v.insert(v.begin(), 500);//在某个位置插入元素
cout<<v[0]<<endl;
cout<< v.front()<<endl;//获取容器中第一个元素
cout<<v.back()<<endl;//获取容器中最后一个元素
cout<<v.max_size()<<endl;//容器的最大容量
cout<<v.capacity()<<endl;//容器当前大小
cout<<v.size()<<endl;//元素个数
v.clear();
cout<<v.size()<<endl;
}
int main(){
func();//容器功能的调用
return 0;
}
//自定义类
class Point{
public:
Point(int _x,int _y){
x=_x;
y=_y;
}
void print(){
cout<<"x="<<x<<endl;
cout<<"y="<<y<<endl;
}
private:
int x;
int y;
};
void func2(){
Point p1(10,20);
Point p2(30,40);
Point p3(50,60);
Point p4(70,80);
vector<Point> p; //
p.push_back(p1);
p.push_back(p2);
p.push_back(p3);
p.push_back(p4);
cout<<p.size()<<endl;
p.at(0).print();
vector<Point*> v; //
v.push_back(&p1);
v.push_back(&p2);
cout<<v.size()<<endl;
v.at(0)->print(); //
}
int main(){
func2();
return 0;
}
6.迭代器:用来遍历容器iterator
使用迭代器,对容器进行元素枚举,使用迭代器也定义在头文件< iterator >
一个迭代器被用来“指向”容器中的元素(虽然不是指针)。迭代器也可以解引用 (*)和进行算术运算。
迭代器可以声明如下格式:
(1)iterator:前向遍历,可读可写
(2)const_iterator:前向遍历,只读
(3)reverse_iterator:后向遍历,可读可写
(4)const_reverse_iterator:后向遍历,只读
迭代器函数:
(1)函数began()返回一个迭代器指向容器的第一个元素。
(2) 函数end()返回一个迭代器指向容量的最后一个元素的下一位置后。
(3)函数rbegin()返回一个迭代器指向容量的最后一个元素。
(4)函数rend()返回一个迭代器指向容量的第一个元素之前的位置。
#include <iostream>
#include<vector>
using namespace std;
class Point{
public:
Point(int _x,int _y){
x=_x;
y=_y;
}
void print(){
cout<<"============"<<endl;
cout<<"x="<<x<<endl;
cout<<"y="<<y<<endl;
}
private:
int x;
int y;
};
void func3(){
Point p1(10,20);
Point p2(30,40);
Point p3(50,60);
Point p4(70,80);
vector<Point> po;
po.push_back(p1);
po.push_back(p2);
po.push_back(p3);
po.push_back(p4);
//创建一个迭代器,指向第一个元素
vector<Point>::iterator itor=po.begin();//迭代器:遍历
while(itor!=po.end())
{
(*itor).print();
itor++;
}
}
int main(){
func3();
return 0;
}
7.容器list的使用
#include <iostream>
#include<list>
using namespace std;
typedef list<int> l;//重新定义类型名字
int main(){
l lst;//list<int> lst
for(int i=0;i<5;i++)
{
lst.push_front(i);
lst.push_back(i);
}
l::iterator itor=lst.begin();
while(itor!=lst.end()){
cout<<*itor++<<endl;
//itor++;
}
cout<<endl;
return 0;
}
8.set
int main(){
//set容器
set<int> s;
s.insert(100);
s.insert(200);
s.insert(300);
s.insert(100);//已经输入一个相同元素,再次输入时,自动忽略。
cout<<s.size()<<endl;
set<int>::iterator itor=s.begin();
while(itor!=s.end()){
cout<<*itor++<<endl;
}
cout<<endl;
multiset<int> ss;
ss.insert(100);
ss.insert(200);
ss.insert(300);
ss.insert(100);//已经输入一个相同元素,再次输入时依然可以存入。
cout<<ss.size()<<endl;
multiset<int>::iterator itor2=ss.begin();
while(itor2!=ss.end()){
cout<<*itor2++<<endl;
}
cout<<endl;
return 0;
}
9.map
#include <iostream>
#include<map>
using namespace std;
int main(){
//map容器
map<string,char> m;
//调用value_type构造函数创建对象后直接插入容器中
m.insert(map<string,char>::value_type("key1",'a'));
m["key5"]='c';//插入数据到容器中(与上一行是等同的功能)
m.insert(map<string,char>::value_type("key1",'f'));//key与value一一映射,key1
m["key3"]='k';
map<string,char>::iterator itor=m.begin();
while(itor!=m.end()){
cout<<itor->first<<endl;
cout<<itor->second<<endl;
itor++;
}
cout<<endl;
cout<<m["key1"]<<endl;
return 0;
}