这篇文章上次修改于 2320 天前,可能其部分内容已经发生变化,如有疑问可询问作者。
3. 一般概念
命名空间(namespace) std
namespace 可以用了解决命名冲突,具有扩展开放性,可以出现在任何源码文件中。c++标准库中的所有标识符都定义在一个名为std的namespace中。
使用标准库标识符,有三种选择
1 直接指定标识符,如std::ostream,
std::cout << std::hex << 3.4 << std::endl;
2 使用using declaration
using std::cout;
using std::endl;
于是之前的例子可以写成
cout << std::hex << 3.4 << endl;
3 使用using directive 如果对namespace std使用using directive 可以让std内定义的所有标识符都有效。
using namespace std;
之后可以写:
cout << hex << 3.5 << endl;
错误处理和异常处理
标准库有一部分支持具体的错误处理,如string class,检查所有可能发生的错误,并在错误发生时抛出异常。其他部分如STL和valarrays,几乎不检查逻辑错误,只会在执行期(runtime)发生错误才抛出异常。
标准异常类可以分为三组:
- 语言本身支持的异常
- C++标准库发出的异常
- 程序作用域(scope of a program)之外发出的异常
语言本身支持的异常:
- 全局操作符new操作失败,抛出bad_alloc异常,该异常可以在任何时间任何较复杂的程序中发生。
- 执行期间,当一个对reference的动态类型转换操作失败时,dynamic_cast会抛出bad_cast异常。
- 执行期类型辨识(RTTI)过程中,如果交给typeid的参数为零或空指针,typeid操作符会抛出bad_typeid异常
如果发生非预期的异常,bad_exception异常会接手处理,方式如下:当函数抛出异常规格(exception specification)以外的异常,bad_exceptio就会调用unexceptiond() 例子:
class E1; class E2; void f() throw(E1) { throw E1(); throw E2(); }
如果在异常规格中列出了bad_exception,那个unexpected()总是会重新抛出(rethrows)bad_exception异常
class E1; class E2; void f() throw(E1, std::bad_exception) { throw E1(); throw E2(); }
C++ 标准库发生的异常
c++标准容器库异常总是派生自logic_error,从理论上讲,我们能够通过一些手段,在程序中避免逻辑错误。所谓逻辑错误包括未被逻辑前提或违背class不变性。- invalid_argument表示无效参数,例如将bitset以char而非‘0’或‘1’进行初始化。
- length_error支出某个行为“可能超越了最大极限”,例如对某个字符串附加太多字符。
- out_of_range指出参数值“不在预期范围内”,例如在诸如array的容器或字符串中采用一个错误索引。
- domain_error指出专业领域范畴的错误
程序作用域之外发生的异常
派生自runtime_error的异常,用来指出“不在程序范围内,且不容易回避”的事件。
- range_error指出内部计算时发生区间错误
- ouverflow_error指出算术运算发生上溢位(overflow)
- underflow_error指出算术运算发生下溢位(underflow)
异常类别的头文件
基础类别exception和bad_exception定义于<exception>。bad_alloc定义于<new>。 bad_cast 和bad_typeid 定义于<typeinfo>。ios_base::failure定义于<ios>。其他异常类型定义于<stdexcept>
异常类别的成员
为了在catch子句中处理异常,必须采用异常提供的接口,所有标准异常的接口只含有一个成员函数:what(),用来获取“类型本身以外的附加信息",返回一个null结束的字符串:
namespace std{
class exception {
public:
virtual const char * what() const throw();
}
}
抛出标准异常:
可以在自己的程序库或程序内部抛出某些标准异常。
logic_error定义如下:
namespace std{
class logic_error: public exception {
public :
explicit logic_error (const string & whatString);
}
}
throw std::out_of_range("out_of_range(somewhere , somehow)")
从标准异常类别中派生新类别
一种使用标准异常的情况,定义一个直接或间接派生自exception的特定异常类别。自己实现what();
namespace MyLib {
class MyProblem :public std::exception {
public:
MyProblem () {
}
virtual const char* what() const throw() {
}
}
...
void f() {
...
throw MyProblem();
}
}
另一种提供what的方式是派生自前面提到的标准异常
namespace MyLib {
class MyRangeProblem : public std::out_of_range {
public:
MyRangeProblem (const string & whatString) :out_of_range (whatString) {
}
}
void f() {
throw MyRangeProblem("here is my special range problem");
}
}
配置器(Allocators)
C++标准程序库在很多地方采用特殊对象来处理内存配置和寻址。这样的对象称为配置器(allocator)。
C++程序库中定义了一个缺省配置器(default allocator):
namespace std{
template <class T>
class allocator;
}
没有评论