ipk*_*iss 23 c++ java exception-handling
在Java中,如果特定的代码行导致程序崩溃,则捕获异常并继续执行程序.
但是,在C++中,如果我有一段导致程序崩溃的代码,例如:
try
{
int x = 6;
int *p = NULL;
p = reinterpret_cast<int*>(x);
*p = 10; // the program crashed here
cout << "x = " << *p << endl;
}
catch(const char* Message)
{
cout << "There is an run-time error";
}
Run Code Online (Sandbox Code Playgroud)
然后程序仍然崩溃,并且没有捕获异常.
那么C++中的异常处理有什么意义呢?我误会了什么吗?
sas*_*ang 31
崩溃的行取消引用无效指针.在C++中,这不会引发异常.相反,它是未定义的行为.
在C++中没有空指针异常这样的东西,不像Java会抛出空指针异常.而取消引用无效指针将导致未定义的行为.未定义的行为并不总是意味着崩溃,但如果它崩溃你很幸运.
C++和Java之间最重要的区别之一是Java支持一个finally语句.在代码finally块总是无论是否与前一代码的运行catch时执行块或没有.例如:
try
{
}
catch (SomeException e)
{
}
finally
{
//code here is always exectued.
}
Run Code Online (Sandbox Code Playgroud)
finally语句的目的是允许程序员在那时进行清理,即释放套接字,关闭文件句柄等......即使Java运行垃圾收集器,垃圾收集也只适用于内存而不适用于其他资源.您仍然需要手动处理资源.现在C++没有finally声明,所以建议语言用户遵守RAII原则(Resouce Acquisition is Initialization)Stroustrup在这里有一个解释:http://www.stroustrup.com/bs_faq2.html#finally.我更喜欢调用它,Resource destruction is deallocation但基本上当你的对象超出范围,调用析构函数时,析构函数应该释放对象维护的任何资源.
例如,C++ 11x提供了一个std :: unique_ptr来管理它:
void foo()
{
std::unique_ptr<T> t(new T)
try
{
//code that uses t
}
catch (...)
{
}
}
Run Code Online (Sandbox Code Playgroud)
new当函数结束时,将删除分配的资源.
因为Exception如果希望catch子句捕获任何异常,Java中的所有异常都从公共基类继承,那么将其设置如下:
catch (Exception e)
{
//any exception thrown will land here.
}
Run Code Online (Sandbox Code Playgroud)
在C++中,对于可以抛出的内容没有限制,并且没有针对所有异常的公共基类.标准做法是通过继承std :: exception来形成自定义异常类,但该语言不强制执行此操作.相反,有一种特殊的语法来捕获所有异常:
catch (...)
{
}
Run Code Online (Sandbox Code Playgroud)
这是语言行为不同的另一个领域.在C++中,未捕获的抛出异常将调用std :: terminate.std :: terminate的默认行为是调用abort,生成SIGABRT并停止整个程序.
在Java中,行为是打印堆栈跟踪并终止未捕获异常发生的线程.但是,由于Java程序员可能提供UncaughtException处理程序,因此行为可能与终止线程的默认行为完全不同.