我正在实施一个Zip-Wrapper(zlib minizip),并问我自己应该怎么做 正确处理异常。我想的是三个版本。哪一个会 你喜欢,还是有一个我没想过的版本?
函数Install
的任务是从Web服务器获取Zip文件,
解压缩其内容并删除下载的Zip文件。但如果出错了
在解压缩文件时会发生Zip-File应该删除的位置?
坦克为您的经验。
版本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
}
答案 0 :(得分: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(以及其他相同问题)。