C++箴言:防范異常離開(kāi)析構(gòu)函數(shù)
發(fā)表時(shí)間:2024-02-18 來(lái)源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]C++ 并不禁止從析構(gòu)函數(shù)中引發(fā)異常,但是這確實(shí)妨礙了實(shí)踐。至于有什么好的理由,考慮: class Widget public: ... ~Widget() ... // assume this might emit an exception ; ...
C++ 并不禁止從析構(gòu)函數(shù)中引發(fā)異常,但是這確實(shí)妨礙了實(shí)踐。至于有什么好的理由,考慮:
class Widget {
public:
...
~Widget() { ... } // assume this might emit an exception
};
void doSomething()
{
std::vector v;
...
} // v is automatically destroyed here
當(dāng) vector v 被析構(gòu)時(shí),它有責(zé)任銷毀它包含的所有 Widgets。假設(shè) v 中有十個(gè) Widgets,在銷毀第一個(gè)的時(shí)候,拋出一個(gè)異常。其他 9個(gè) Widgets 仍然必須被銷毀(否則他們持有的任何資源將被泄漏),所以 v 應(yīng)該調(diào)用它們的析構(gòu)函數(shù)。但是假設(shè)在這個(gè)調(diào)用期間,第二個(gè) Widgets 的析構(gòu)函數(shù)又拋出一個(gè)異常,F(xiàn)在有兩個(gè)異常同時(shí)在活動(dòng)中,對(duì)于 C++ 來(lái)說(shuō)這太多了。在非常巧合的條件下發(fā)生這樣兩個(gè)同時(shí)活動(dòng)的異常,程序的執(zhí)行會(huì)終止或者引發(fā)未定義行為。在本例中,將引發(fā)未定義行為。與此相同,使用任何標(biāo)準(zhǔn)庫(kù)容器(比如,list,set),任何 TR1中的容器,甚至是一個(gè)數(shù)組,都可能會(huì)引發(fā)未定義問(wèn)題。并非必須是容器或數(shù)組才會(huì)陷入麻煩。程序夭折或未定義行為是析構(gòu)函數(shù)引發(fā)異常的結(jié)果,即使沒(méi)有使用容器或數(shù)組也會(huì)如此。C++ 不喜歡引發(fā)異常的析構(gòu)函數(shù)。 這比較容易理解,但是如果你的析構(gòu)函數(shù)需要執(zhí)行一個(gè)可能失敗而拋出異常的操作,該怎么辦呢?例如,假設(shè)你與一個(gè)數(shù)據(jù)庫(kù)連接類一起工作:
class DBConnection {
public:
...
static DBConnection create(); // function to return
// DBConnection objects; params
// omitted for simplicity
void close(); // close connection; throw an
}; // exception if closing fails