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的專欄