1)为方便起见,我将整个程序放在try块中。这样我就可以在代码中的任何一点抛出异常,并知道它将以相同的方式处理。随着程序变得更大,这种技术会导致性能下降吗?
2)如果在超出范围时取消分配对象,为什么抛出临时对象有效? e.g:
class Error : public std::exception { private: char *m; private: Error(char *l) : m(l) {} virtual char *what() { return m; } }; int main() { try { throw Error("test"); } catch(std::exception &e) { puts(e.what()); return -1; } return 0; }
在throw语句中,为什么临时对象不会变为无效,因为它只在try范围内声明?
3)对于非英语语言的Windows操作系统,STL异常类的what()
成员是否仍会返回char*
字符串?或者它可以返回wchar_t*
字符串吗?
答案 0 :(得分:10)
从技术上讲,你不会抛出实际的对象,而是抛出它的副本。这就是为什么你可以放弃一个临时的。捕获引用也可以获得对副本的引用。
如果你从catch块中重新抛出异常,这可能会让你感到厌烦,你可能成为切片问题的牺牲品。这就是你不这样做的原因:
catch (std::exception & e)
{
throw e; // bad, always throws std::exception rather than what was caught
}
而是
catch (std::exception & e)
{
throw; // good, rethrows the exact copy that you caught without making another copy
}
P.S。没有规则说您无法从what
返回UTF-8字符串。您可以将它转换为Windows I / O的UTF-16。从未为Unicode明确设计或扩展标准异常类,也没有为Windows添加任何非标准扩展。
答案 1 :(得分:4)
1) 将整个程序置于try块中不会产生任何性能损失,除了启用异常所带来的性能
2) 这是好的,因为你是按价值投掷。按值投掷意味着投掷时抛出的任何内容都会被复制。所以扔任何临时都是完全有效的,因为副本已经完成。
3)
据我所知,std :: exception类只能抛出char*
。但是,如果需要,您可以始终对其进行子类化并实现对wchar的支持。
值得注意的是,如果这是你想要的,你不应该只是尝试捕捉main()
。