2010-09-23 83 views
1

我正在實施一個Zip-Wrapper(zlib minizip)並詢問我自己應該如何正確處理異常 。我正在考慮三個版本。哪一個你會喜歡 ,還是有我沒有想過的版本?三個異常處理版本,哪一個更好?

函數Install的任務是從Web服務器獲取Zip文件, 解壓其內容並刪除下載的Zip文件。但是如果在解壓縮文件時發生錯誤 ,應該在哪裏刪除Zip文件?

坦克爲您的經驗。

版A(與刪除功能外):

void Install() { 
    getFile("upd.zip"); // Creates File 
    MyZip myzip("upd.zip"); 
    myzip.unzip();  // Can't do its job --> Exception 
    delete("upd.zip"); // In case of exception: File would not be deleted here 
} 

int main() { 
    try { 
     Install(); 
    } 
    catch (const Error& err) { 
     delete("upd.zip"); // File must be deleted here 
     MessageBox(err.text); 
    } 
} 

版本B(與重新拋出異常)

void Install() { 
    getFile("upd.zip"); // Creates File 
    try { 
     MyZip myzip("upd.zip"); 
     myzip.unzip(); 
    } 
    catch (const Error& err) { 
     delete("upd.zip"); 
     throw err; // Re-Throw the Error 
    } 
    delete("upd.zip"); 
} 

int main() { 
    try { 
     Install(); 
    } 
    catch (const Error& err) { 
     MessageBox(err.text); 
    } 
} 

版C(與返回代碼)

void Install() { 
    getFile("upd.zip"); // Creates File 
    MyZip myzip("upd.zip"); 
    if (!myzip.unzip("upd.zip")) { 
     delete("upd.zip"); 
     throw Error(myzip.geterror()); // what was the reason 
    } 
    delete("upd.zip"); 
} 

int main() { 
    // Same as in Version B 
} 

回答

3

三者中沒有一個。使用RAII

class FileGuard { 
public: 
    FileGurad(const std::string & filePath) 
    : m_FilePath(filePath) 
    {} 

    ~FileGuard() { 
     delete(m_FilePath); // must not throw an exception 
    } 
private: 
    std::string m_FilePath; 
}; 

用法:

void Install() { 
    guard FileGuard(getFile("upd.zip")); // Creates File; getFile should return the path where the file was created 
    MyZip myzip("upd.zip"); 
    myzip.unzip();  // Can't do its job --> Exception 
    // file will be deleted when guard goes out of scope (e.g. when an expection is thrown) 
} 

或者你可以有FileGuard通話getFile在構造函數中。有關堆棧展開(尤其是銷燬順序)的更多信息,請參見this answer(以及其他相同的問題)。

+0

感謝您的回答。我這樣做了。是否銷燬類實例的順序始終相同(首先創建=最後銷燬)?我問,因爲在RAII的意義上,我給出了關閉MyZip析構函數中的zip文件的部分。因此MyZip實例應該在FileGuard實例之前銷燬。 – 2010-09-23 10:28:47

+0

@Christian:我爲您的訂單問題添加了一個鏈接。 – 2010-09-23 10:34:43