一个常见的编程习惯是在空闲存储区中动态分配内存(可能是对象),将该内存的地址赋给一个指针,使用这个指针操作内存,并在该内存不再需要时用delete释放内存。如果内存分配之后和执行delete语句之前发生异常,则可能发生内存泄漏。ANSI/ISO C++草案标准提供<memory>头文件中的auto_ptr类模板,可以解决这个问题。
auto_ptr类对象维护动态分配内存的指针。当auto_ptr对象超出范围时,对指针数据成员进行一个delete操作。auto_ptr类模板提供了+和- >运算符.因此auto_ptr对象可以像普通指针变量一样使用。图13.7演示auto_ptr对象指向Integer类对象(在第8行到第18行定义)。
// Fig. 13.7: fig13_07.cpp // Demonstrating auto_ptr #include <iostream> #include <memory> using namespace std; class Integer { public: Integer( int i = 0 ) : value( i ) {cout << "Constructor for Integer " << value << endl; } ~Integer() {cout << "Destructor for Integer " << value << endl; } void setInteger( int i ) { value = i; } int getInteger() const { return value; } private: int value; }; int main() { cout << "Creating an auto_ptr object that points " << "to an Integer\n"; auto_ptr< Integer > ptrToInteger( new Integer( 7 ) ); cout << "using the auto_ptr to manipulate the Integer\n"; ptrToInteger->setInteger( 99 ); cout << "Integer after setInteger: " << ( *ptrToInteger ).getInteger() << "\nTerminating program" << endl; return 0; }
Creating an auto_ptr object that points to an Integer Constructor for Integer 7 Using the auto_ptr to manipulate the Integer Integer after setInteger: 99 Terminating program Destruct for Integer 99
第25行: auto_ptr<Integer> ptrToInteger(new Integer(7 ));
生成aut_ptr对象ptrToInteger并用动态分配Inleger对象的指针(包含数值7)初始化。
第28行:
ptrToInteger- >setInteger(99);用auto_ptr重载->运算符和函数调用运算符()调用ptrToInteger所指Integer对象的setInteger函数。
第30行:
(*ptrToInteger).getInteger()用auto_ptr重载*运算符复引用ptrToInteger,然后用圆点运算符和函数调用运算符()调用ptrTolmeger所指Integer对象的getInteger函数。
由于ptrToInteger是main中的局部自动变量,因此main终止时删除ptrToInteger。这样就强制删除ptrToInteger所指的Integer对象,从而强制调用Integer类的析构函数。更重要的是这个方法可以防止内存泄漏。经验表明,异常是可以分类的。C++草案标准提供了标准库异常层次。这个层次以基类excephon开始(在头文件<exception>中定义),该基类提供服务what(),在每个派生类中重定义,发出相应的错误消息。
从基类exception可以派生直接派生类runtime_error和Iogic_error(都在头文件 <stdexcept>中定义),每个派生类又可以派生其他类。
从exception中还可以派生由于C++语言特性而抛出的异常,例如,new抛出bad_alloc(13.14节).dynamic_cast抛出bad_cast(第2l章),typeid抛出bad_typeid(第21章)。如果发生意外异常时,通过在函数的抛出表中加上std::bad_exeeption,unexpected()抛出bad_exception而不是(默认)终止程序或调用set_unexpected指定的另一函数。
logic_error类是几个标准异常类的基类,表示程序逻辑中的错误,可以通过编写正确的代码来防止。下面介绍其中的一些类。invalid_argument类表示向函数传入无效参数(可以通过编写正确的代码来防止)。length_error类表示长度大于所操作对象允许的最大长度(第19章处理string时会抛出length_error异常)。out_of_range类表示数组和string下标之粪的值超界。
runtime_error类是几个其他异常类的基类,表示程序中只能在执行时发现的错误。overflow_error类表示发生运算上溢错误;underflow_error类表示发生运算下溢错误。
标准exception层次只是一个起点.用户可“抛出标准异常、抛出从标准异常派生的异常或抛出不是从标准异常派生的异常。
用户自定义异常类不一定从exception类派生。 因此catch(exception并井不保证捕获程序可能遇到的各种异常。