1.异常
1.00 以下展示了一种异常机制使用的框架
namespace Stack{
void push(char);
class Overflow{/*....*/};//设置异常
//...
}
void Stack::push(char c){
if(top==max_size)throw Overflow();//抛出异常
//...
}
void f(){
//...
try{
Stack::push('c');
}
catch(Stack::Overflow){
//...异常处理
}
}
2.用户定义类型
2.00 构造函数与析构函数
class complex{
double re,im;
public:
/*与类名相同的函数为构造函数,构造函数不唯一*/
complex(double r, double i){re=rim=m;};
complex(double r){re=r,im=0;};
complex(){re=im=0;};
/*显然,在函数名为“~classname"的成员函数为析构函数*/
~complex(){/*...*/};
//...
}
2.01 虚函数与派生类
在基类里声明virtual func
在派生类里定义func
以实现最大的灵活性
class Stack{
public:
//...
virtual void push(char c)=0;// '=0'表示在派生类里必须定义这个函数
//...
}
class arry_stack :public Stack{ //":public classname" 表示由class classname 派生
//...
public:
//...
}
2.1模板(template)
模板刻画一族函数
2.10 最常见的是引进类参数的模板
template<class Type> class Stack{
Type* v;//不再局限于某种特定类型
public:
//...
T pop();
}
template<class Type> Type Stack<Type>::pop(){//一种定义成员函数的方式(真是相当啰嗦的方式)
//...
}
2.11多个参数
template <typename T, int n>
T Array<T, n>::operator[](int i) const {
if (i < 0 || i >= n) {
//...
}
//...
}
//n是传入表达式的参数
但是只接受 int,enum,指针类型
(比如禁止double允许double*)
3.通用型算法
关键是通过迭代器(iterator)对序列进行操作
3.0迭代器
迭代器:引用一个元素,并提供获得下一个元素的操作
链结点 就是一个迭代器
3.1容器
例如基本原子容器(vector,list,map),所有容器都提供 .begin() .end() 这两个迭代器
.begin()引用的是开始元素,.end()引用的是最后一个元素的下一个位置。它们本质上是指针,也因此可以用指针这种低级方式代替。
3.2标准库容器
3.20 string
std
string s1="abc",s2;
s2=s1+"def"+"g"+'\n';//可以直接将字符串、字符串文字量、单字符字符串、字符直接拼接
s2+=s1;
s1==s2||s1=="abcdef";//可以直接将字符串、字符串文字量判等
s1.replace(0,2,"hjkl");//替换目标与源串不必相等
3.21输入
std
string s;
cin >>s;//然而需要注意的是依旧以空白字符(比如空格)为输入结束的标志
getline(cin,s);//整行输入
3.22原子容器
所有序列容器均以(vector,list,map)这三种容器为基础
a.vector
向量,顺序结构:便于随机访问,不便于插入删除 <vector> std
struct Entry{
string name;
int number;
}
vector<Entry>phone_book[1000];//但是vector并不提供范围检查,越界访问问可能会得到一个随机值
Vec<Entry>phone_book[1000];//Vec提供边界检查,越界时抛出 out_of_range 异常
b.list
表(双头),链式结构:便于插入删除,不便于随机访问(但依旧是瞬时访问,不知怎么实现的) <list> std
list<Entry>phone_book;
typedef list<Entry>::const_iterator LI;//只是读取时使用const_iterator
for(LI i=phone_book.begin();i<phone_book.end();++i){
//...
}
void add_entry(Entry& e,list<Entry>::iterator i){
phone_book.push_front(e);//加在开头
phone_book.push_back(e);//加在结尾
phone_book.insert(i,e);//加在迭代器i 之前
}
c.map
映射:便于插入删除,以及基于值的随机访问 <map> std
map<string,int>phone_book;
void f(const string& s){
int i=phone_book[s];
//...
}