Thinking in C++ 學習筆記[1]

 Thinking in C++ 學習筆記[1]

setjmp、longjmp不適合c++的類機制

setjmp和longjmp是c中的庫函數,其對應的頭文件是<setjmp.h>,在c++中其對應的頭文件爲<csetjmp>.
setjmp和longjmp爲非本地化的goto函數。 首先setjmp()保存了當前程序運行時的狀態,當你遇到麻煩的時候, 調用longjmp可以恢復到剛纔保存的狀態。
但setjmp和longjmp不適合c++, 因爲setjmp和longjmp不會調用對象的析構函數。
看下面這個例子:
#include <iostream>
#include <csetjmp>

using namespace std;

class Rainbow {
public:
    Rainbow() {cout << "Rainbow()";}
    virtual ~Rainbow() {cout << "~Rainbow()";}
};
jmp_buf kansas;

void oz() {
    Rainbow r;
    for(int i = 0; i < 3; i++) {
        cout << "there is no place like home" << endl;
    }
    longjmp(kansas, 47);
}

int main() {
    if (setjmp(kansas) == 0) {
        cout << "tornado, witch, munchkins..." << endl;
        oz();
    } else {
        cout << "Auntie em!!!!";
    }
}

程序的運行結果
tornado, witch, munchkins...
Rainbow()
there is no place like home
there is no place like home
there is no place like home
Auntie Em!

可以看到Rainbow對象的析構函數沒有被執行, 這是因爲setjmp(kansas)的時候, 保存了當前的進程的狀態, 包括當前instruction pointer的值和函數棧指針的值。
當調用longjmp,就回到setjmp執行時的狀態,此時setjmp返回longjmp的第二個參數,所以對象的析構函數就不會被執行。

發佈了31 篇原創文章 · 獲贊 3 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章