我一直认为,如果一个方法可以抛出一个异常,那么不顾及用一个有意义的try块来保护这个调用.
我刚刚发布了' 你应该总是包装可以抛出try,catch块的调用.'对这个问题,并被告知这是'非常糟糕的建议' - 我想明白为什么.
我对异常处理的理解很差(即,如何根据自己的目的自定义throw,try,catch语句).
例如,我已经定义了一个函数如下: int compare(int a, int b){...}
当a或b为负时,我希望函数抛出一些带有异常消息的异常.
我应该如何在函数的定义中处理这个问题?
如果抛出异常,我想有办法向用户报告堆栈跟踪.做这个的最好方式是什么?是否需要大量的额外代码?
回答问题:
如果可能的话,我希望它是便携式的.我想要弹出信息,因此用户可以复制堆栈跟踪并在出现错误时通过电子邮件发送给我.
catch中的以下append()是否会导致重新抛出的异常以查看append()被调用的效果?
try {
mayThrowMyErr();
} catch (myErr &err) {
err.append("Add to my message here");
throw; // Does the rethrow exception reflect the call to append()?
}
Run Code Online (Sandbox Code Playgroud)
类似地,如果我以这种方式重写它,如果myErr导出实际异常,是否会发生位切片?
try {
mayThrowObjectDerivedFromMyErr();
} catch (myErr &err) {
err.append("Add to my message's base class here");
throw err; // Do I lose the derived class exception and only get myErr?
}
Run Code Online (Sandbox Code Playgroud) 我已经看到至少一个可靠的源(我采用的C++类)建议C++中特定于应用程序的异常类应该继承std::exception.我不清楚这种方法的好处.
在C#中,继承的原因ApplicationException很明确:你得到了一些有用的方法,属性和构造函数,只需要添加或覆盖你需要的东西.有了std::exception这一切似乎你得到的是一个what()覆盖方法,你也可以同样创造自己.
那么,如果有的话,std::exception作为特定于应用程序的异常类的基类有什么好处呢?有没有好的理由不继承std::exception?
当我的C++方法遇到奇怪但无法恢复的东西时,我想抛出异常.投掷是否可以std::string指针可以吗?
这是我期待的事情:
void Foo::Bar() {
if(!QueryPerformanceTimer(&m_baz)) {
throw new std::string("it's the end of the world!");
}
}
void Foo::Caller() {
try {
this->Bar(); // should throw
}
catch(std::string *caught) { // not quite sure the syntax is OK here...
std::cout << "Got " << caught << std::endl;
}
}
Run Code Online (Sandbox Code Playgroud) 什么是一组异常类的好设计?
我看到各种各样的东西,关于什么异常类应该和不应该做什么,但不是一个简单的设计,易于使用和扩展,做那些事情.
让1和4一起工作是我遇到的最大问题,因为任何格式化和文件输出方法都可能失败.
编辑:所以看了几个类中的异常类,并且在Neil链接的问题中,似乎通常的做法是完全忽略第1项(因此提升建议),这似乎是一个相当糟糕的想法我.
无论如何,我以为我也会发布我正在考虑使用的异常类.
class Exception : public std::exception
{
public:
// Enum for each exception type, which can also be used
// to determine the exception class, useful for logging
// or other localisation methods for generating a
// message of some sort.
enum ExceptionType
{
// Shouldn't ever be thrown
UNKNOWN_EXCEPTION = 0,
// The same as above, but it has a string that
// may provide some information
UNKNOWN_EXCEPTION_STR,
// For …Run Code Online (Sandbox Code Playgroud) 今天,在我的C++多平台代码中,我对每个函数都进行了尝试.在每个catch块中,我将当前函数的名称添加到异常并再次抛出,以便在最上面的catch块(我最终打印异常的详细信息)中,我有完整的调用堆栈,这有助于我跟踪异常的原因.
这是一个好习惯,还是有更好的方法来获取异常的调用堆栈?
我想处理我的c ++程序中的错误,所以我创建了一些异常类来管理这些错误,但是我想指定程序中哪一行发生了错误.
我将LINE宏传递给我的异常类的构造函数.
例如:
void f(int i){ // LINE A
if(i<0)
throw(OutOfRange("message", __LINE__); // LINE B
}
void main(){
try{
f(-6); // LINE C
}
catch(const OutOfRange& error){
//do something
}
}
Run Code Online (Sandbox Code Playgroud)
在这个例子中,我只能获得LINE B编号,但我想获得LINE A和LINE C编号.
任何想法,在哪里以及如何使用LINE宏?
谢谢.
我正在寻找MS VC++中的答案.
在调试大型C++应用程序时,遗憾的是它具有非常广泛的C++异常用法.有时我会比实际想要的晚一点捕获异常.
伪代码示例:
FunctionB()
{
...
throw e;
...
}
FunctionA()
{
...
FunctionB()
...
}
try
{
Function A()
}
catch(e)
{
(<--- breakpoint)
...
}
Run Code Online (Sandbox Code Playgroud)
我可以在调试时用断点捕获异常.但是,如果异常发生在FunctionA()或FunctionB(),或其他一些功能,我无法追溯.(假设广泛的异常使用和上述示例的巨大版本).
我的问题的一个解决方案是在异常构造函数中确定并保存调用堆栈(即在捕获之前).但这需要我从这个基类异常类派生所有异常.它还需要很多代码,并且可能会减慢我的程序速度.
是否有更简单的方法需要更少的工作?无需更改我的大代码库?
在其他语言中是否有更好的解决方案?
我刚刚完成了一个C++程序,我已经实现了自己的异常(虽然派生自std :: exception).当一个异常导致连锁反应,向上传播错误并引起其他异常时,我应用的做法是在模块的每个适当步骤(读取类)中连接错误消息.即旧的异常本身被删除并创建一个新的异常,但是有一个更长的错误消息.
这可能适用于我的小程序,但我最终对我的方法不太满意.例如,除最后一个异常外,不保留行号(虽然目前不应用)和文件名; 实际上,在第一个例外中,这些信息最受关注.
我认为通过将异常链接在一起可以更好地处理这个问题; 即在新异常的构造函数中提供旧异常.但是如何实施呢?当它们超出方法的范围时,异常是否会死亡,从而阻止使用异常指针?如果异常可以是任何派生类,如何复制和存储异常?
这最终促使我考虑在C++中链接异常是否是一个好主意.也许应该只创建一个异常然后添加额外的数据(就像我一直在做的那样,但可能会以更好的方式)?
你对此有何回应?是否应将由另一个引起的异常链接在一起以保留某种"异常追踪" - 以及如何实施? - 或者是否应该使用单个例外并附加其他数据 - 应该如何做?
我有一个c ++应用程序,它在try块中包含大部分代码.当我捕获异常时,我可以将用户返回到稳定状态,这很好.但我不再接收崩溃转储了.我真的想弄清楚代码中的异常发生在哪里,所以我可以记录并修复它.
能够在不停止应用程序的情况下获得转储将是理想的,但我不确定这是否可行.
有什么方法可以找出catch块中抛出异常的位置?如果它有用,我在windows xp及更高版本上使用本机msvc ++.我的计划是简单地将崩溃记录到各个用户的计算机上的文件中,然后在达到一定大小后上载崩溃日志.
寻找一种快速而又脏的方法来识别构造函数的调用者(或任何函数)我正在编写宏来帮助通过转储this指针来识别内存泄漏OutputDebugString.
知道调用ctor和dtor的位置有助于识别问题.
tnx\0
c++ ×13
exception ×11
try-catch ×2
visual-c++ ×2
callstack ×1
chaining ×1
java ×1
line ×1
logging ×1
memory-leaks ×1
rethrow ×1
stack-trace ×1
stl ×1
winapi ×1
windows ×1