简体   繁体   English

在 C++ 中引发和捕获自定义异常的问题

[英]Problem throwing and catching custom exceptions in C++

I've created the class Someting which throws an exception SomethingException (SomethingException inherits from std::exception) when it fails to instantiate.我创建了 class Someting ,它在实例化失败时抛出异常SomethingException (SomethingException 从 std::exception 继承)。 the problem is I can't catch SomethingException as such (I had to do a dirty trick to catch it).问题是我不能像这样捕获SomethingException (我不得不做一个肮脏的把戏来捕获它)。

There is somewhere in the program where it executes: This doesn't work , the exception is not caught and the program crashes.它在程序中执行的某个地方:这不起作用,未捕获异常并且程序崩溃。

try{
    Something* s = new Something();
}
catch (SomethingException* e){
    std::cerr<<e.what();
}

In contrast this does work (exception is caught and the correct message shown) but I really have the feelin I shouldn't be doing this相比之下,这确实有效(异常被捕获并显示了正确的消息)但我真的觉得我不应该这样做

try{
    Something* s = new Something();
}
catch (std::exception* e){
    SomethingException* e2 = (SomethingException*) e;
    std::cerr<<e.what();
}

Because the pointer is casted I can only make this work if and only if one type of exception is thrown.因为指针是强制转换的,所以只有当且仅当引发一种异常时,我才能使其工作。 The moment I need to catch various types this won't work.在我需要捕捉各种类型的那一刻,这是行不通的。

Is there a way to caught a custom exception in a more correct way?有没有办法以更正确的方式捕获自定义异常?

Edit:编辑:

The exception is thrown as follows抛出异常如下

//...
throw new SomethingException ("Errormessage"); //Custom exception constructor
//...

The declaration of Something::Something() is Something::Something() 的声明是

Something::Something() throw(...)

Using the declaration使用声明

Something::Something() throw(SomethingException)
//or
Something::Something() throw(SomethingException*)

Throws a lot of warnings (Warning C4290)引发大量警告(警告 C4290)

In general it's best to throw exceptions by value and catch them by reference:一般来说,最好按值抛出异常并通过引用捕获它们:

try {

    throw SomethingException();

} catch (const SomethingException& error) {

    std::cerr << error.what() << '\n';

}

You would only be able to catch an exception with catch (SomethingException*) if you were to throw it with throw new SomethingException() .如果要使用throw new SomethingException()异常,则只能使用catch (SomethingException*)捕获异常。 There isn't enough information in your question to tell, but the problem may be in how SomethingException derives from std::exception .您的问题中没有足够的信息可以说明,但问题可能在于SomethingException如何从std::exception派生。 Verify that or change it to inherit from, say, std::runtime_error or std::logic_error instead.验证或将其更改为从std::runtime_errorstd::logic_error

Also, don't use throw specifiers.另外,不要使用throw说明符。 Just don't.只是不要。 No compiler affords any benefit to using checked exceptions: in effect, checked exceptions aren't checked except to fail horribly (throwing std::bad_exception ) in the event of an exception that doesn't conform to the specifier.没有编译器为使用检查异常提供任何好处:实际上,检查异常不会被检查,除非在发生不符合说明符的异常时可怕地失败(抛出std::bad_exception )。 That's probably what's happening in your code.这可能就是您的代码中发生的事情。

For others who may have the problem where a custom exception, derived from std::exception, is being thrown but not caught, also check: - That the inheritance is public - If your exception is declared in another DLL, that the exception class is exported from the DLL.对于可能遇到从 std::exception 派生的自定义异常被抛出但未捕获的问题的其他人,还要检查: - inheritance 是公共的 - 如果您的异常在另一个 DLL 中声明,则异常 ZA2F2ED4F8EBC2CBBDDZC2 是从 DLL 导出。 Strangely, if it is not, this does not produce a link error (in VS2012), it just fails to be caught.奇怪的是,如果不是,这不会产生链接错误(在 VS2012 中),它只是未能被捕获。

Can you show the code where you throw the exception.你能显示你抛出异常的代码吗?

Another point is about throw-specifications - it's generally a bad idea.另一点是关于 throw-specifications - 这通常是一个坏主意。 The problem is that C++, unlike Java, doesn't insist on throw-specs and so you get next to no benefit from them.问题是 C++ 与 Java 不同,它不坚持抛出规格,因此您几乎不会从中受益。 All that they can do is potentially cause a core dump if your code (or some code that you call) throws an exception that isn't specified in the throw-spec如果您的代码(或您调用的某些代码)抛出未在 throw-spec 中指定的异常,他们所能做的就是可能导致核心转储

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM