命名空间
名字空间
名字空间是一种描述逻辑分组的机制。
namespace Parser{
double prim(bool);
double term(bool);
double expr(bool);
}
double Parser::prim(bool get){/*...*/} //界面和实现分离,通过限定词明确作用域
double Parser::term(bool get){/*...*/}
double Parser::expr(bool get){/*...*/}
使用声明/指令
当某个名字在自己命名空间之外频繁使用时,每次都加上限定词是比较繁琐的,可以通过使用声明的方式。
namespace test{
int i;
float f;
int test();
}
using test::i; //使用声明,在这个作用域中i就是test::i
i=0;
using namespace test;//使用指令能把来自一个名字空间中所有名字变成可用的
避免名字空间冲突
名字空间太短,名字可能出现冲突;太长在实际代码中又不实用;所以往往通过为长名字提供较短的别名的方式解决。
namepace American_Telphone_and_Telegraph{
//...
}
namespace ATT=American_Telphone_and_Telegraph;
ATT::String s3="Grid";
ATT::String s4="Micheal";
无名名字空间:有时候仅仅将一组声明包裹在一个名字空间中避免可能的名字冲突,此时无需提供用户界面。
namespace{//等价于后面的样例 int a; float f(); int g(); } | namespace $$${ //$$$是在该名字空间中唯一的名字 using namespace $$$ |
可在该文件中直接使用,感觉和没有使用命名空间的效果一样。
名字空间组合和选择
namespace His_string{
class String{/*...*/};
String operator+(const String &,const String &);
}
namespace Her_verctor{
template<class T> class Vector{{/*...*/};
class String{/*...*/};
}
namespace My_lib{
using His_string::Operator+; //选择
using namespace Her_vector; //如果在My_lib中未见到某个声明,编译器将会去Her_vector中去找
using Her_vector::String; //以倾向Her_vector的方式解析潜在冲突,与函数重载/类的继承相似
void my_fct(String&);
}
多重界面
namespace Parser_interface{
double expr(bool); //用户界面
}
namespace Parser{
double prim(bool);
double expr(bool); //重复的定义会报错,重复的声明OK,是因为命名空间的开放性
using Lexer:get_token;}
//方式1新定义一个用户界面名称,直接调用
namespace Parser_interface{
using Parser::expr(bool);
}
//方式2在新的用户界面名称中调用内部界面函数
namespace Parser_interface{
double expr(bool get){return Parser::expr(get)};
}
名字空间和重载
namespace A{
void f(int);
}
namespace B{
void f(char);
}
namespace Mine{
using namespace A;
using namespace B;
void f(int); //在mine名字空间中f(int)应该用自己定义的
}
namespace Mine{
void g(float); //重新打开(开放的),可以新增成员;一般不建议这样使用,因为不知道是要调用还是重新声明一个函数
}
小结
名字空间描述了一个具有逻辑同意性的特征集合,可有效解决名字冲突问题;
具有开放(可不断补充)、继承、重载等特征,可以进行灵活组合(先有namespace机制后有类?);
兼容性的设计先用不上,暂不学习和考虑了。
异常
当一个程序由一些相互分离的模块组成时,特别是当这些模块来自某些独立开发的库时,错误处理的工作就需要分成两个互相独立的部分:
1、一方报告出那些无法在局部解决的错误;
2、另一方处理那些在其他地方检查出的错误。
//此处仅给出一个简单的异常应用,了解基本异常处理,高级特性和应用待后续学习
#include<iostream>
#include<limits>
using namespace std;
struct Range_error{
int i;
Range_error(int j){i=j;}
};
char to_char(int i){
if(i<numeric_limits<char>::min()||numeric_limits<char>::max()<i)
throw Range_error(i);
return i;
}
int main(){
int test;
cout<<"Please input the number"<<endl;
cin>>test;
try{
char c=to_char(test);
cout<<c<<endl;
}
catch(Range_error x){
cout<<"The num is out of range "<<x.i<<endl;
}
catch(...){ //表示其他未特定的异常
cout<<"Unexcepted error"<<endl;
}
}