当前位置:编程学习 > C/C++ >>

第17章 用于大型程序的工具(6)

17.1.10 异常说明

异常说明(exception specification)指定,如果函数抛出异常,则抛出的异常将是包含在该说明中的一种,或者是从列出的异常中派生的类型。

auto_ptr的缺陷

(1)不要使用auto_ptr对象保存指向静态分配对象的指针。

(2)永远不要使用两个auto_ptr对象指向同一对象。

(3)不要使用auto_ptr对象保存指向动态分配数组的指针。

(4)不要将auto_ptr对象存储在容器中。

1. 定义异常说明

异常说明跟在函数形参表之后。一个异常说明在关键字throw之后跟着一个(可能为空的)的圆括号括住的异常类型列表。

void Method1()throw (runtime_error){ 
    try 
    { 
        throw range_error("error~"); 
    } 
    catch(...)  
    { 
        throw;          
    } 

void Method1()throw (runtime_error){
 try
 {
  throw range_error("error~");
 }
 catch(...)
 {
  throw;        
 }
}空说明列表指出函数不抛出任何异常。

size_type size(const BaseManager &i) const throw (){ 
    return items.count(i); 

 size_type size(const BaseManager &i) const throw (){
  return items.count(i);
 }

异常说明是函数接口的一部分,函数定义以及该函数的任意声明必须具有相同的异常说明。

如果一个函数声明没有指定异常说明,则该函数可以抛出任意类型的异常。

2. 违反异常说明

如果函数抛出了没有在其异常说明中列出的异常,就调用标准库函数unexpected。默认情况下,unexpected函数调用terminate函数,terminate函数一般会终止程序。

在编译的时候,编译器不能也不会试图验证异常说明。

编译器会产生代码以便保证,如果抛出了一个违反异常说明的异常,就调用unexpected函数。

3. 确定函数不抛出异常

异常说明有用的一种重要情况是,如果函数可以保证不会抛出任何异常。

知道函数不抛出异常会简化编写调用该函数的异常安全的代码的工作,我们可以知道在调用函数时不必担心异常,而且如果编译器知道不会抛出异常,它就可以执行被可能抛出异常的代码所抑制的优化。

4. 异常说明与成员函数

在const成员函数声明中,异常说明跟在const限定符之后。

size_type size(const BaseManager &i) const throw (){ 
    return items.count(i); 

 size_type size(const BaseManager &i) const throw (){
  return items.count(i);
 }5. 异常说明与析构函数

class isbn_mismatch:public logic_error{ 
public: 
    explicit isbn_mismatch(const string &message):logic_error(message){} 
    isbn_mismatch(const string &message, const string &lhs, const string &rhs) 
        :logic_error(message),left(lhs),right(rhs){} 
    const string left,right; 
    virtual ~isbn_mismatch() throw(){} 
}; 
class isbn_mismatch:public logic_error{
public:
 explicit isbn_mismatch(const string &message):logic_error(message){}
 isbn_mismatch(const string &message, const string &lhs, const string &rhs)
  :logic_error(message),left(lhs),right(rhs){}
 const string left,right;
 virtual ~isbn_mismatch() throw(){}
};6. 异常说明与虚函数

基类中虚函数的异常说明,可以与派生类中对应虚函数的异常说明不同。

但是,派生类虚函数的异常说明与对应基类虚函数的异常说明同样严格,或者比后者更受限。

这个限制保证,当使用指向基类类型的指针调用派生类虚函数的时候,派生类的异常说明不会增加新的可抛出异常。

基类中的异常列表是虚函数的派生类版本可以抛出的异常列表的超集。

class Book{ 
public: 
    virtual void Method1() throw(logic_error){} 
}; 
 
class NoteBook:public Book{ 
public: 
    void Method1() throw(isbn_mismatch){} 
}; 
class Book{
public:
 virtual void Method1() throw(logic_error){}
};

class NoteBook:public Book{
public:
 void Method1() throw(isbn_mismatch){}
};17.1.11 函数指针的异常说明

异常说明是函数类型的一部分。这样,也可以在函数指针的定义中提供异常说明。

在另一指针初始化带异常说明的函数的指针,或者将后者赋值给函数地址的时候,两个指针的异常说明不必相同,但是源指针的说明必须至少与目标指针的一样严格。

class Book{ 
public: 
    virtual void Method1() throw(logic_error){} 
}; 
 
class NoteBook:public Book{ 
public: 
    void Method1() throw(isbn_mismatch){} 
}; 
class Book{
public:
 virtual void Method1() throw(logic_error){}
};

class NoteBook:public Book{
public:
 void Method1() throw(isbn_mismatch){}
};Book book=Book(); 
NoteBook notebook=NoteBook(); 
void (Book::*func_p)() throw(logic_error)=&(Book::Method1); 
(book.*func_p)(); 
(notebook.*func_p)(); 

 摘自 xufei96的专栏
 

补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,