C ++和Java中异常处理的区别? [英] Difference between exception handling in C++ and Java?

查看:136
本文介绍了C ++和Java中异常处理的区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Java中,如果特定的代码行导致程序崩溃,那么异常被捕获,程序继续执行。



然而,在C ++中,如果我有一段导致程序崩溃的代码,如:

  try 
{
int x = 6;
int * p = NULL;
p = reinterpret_cast< int *>(x);

* p = 10; //程序在这里崩溃

cout<<< x =< * p < ENDL;
}
catch(const char * Message)
{
cout<<< 有运行时错误;
}

然后程序仍然崩溃,异常未被捕获。



那么C ++中的异常处理是什么意思?我误解了一些东西吗?

解决方案

崩溃的行是取消引用无效指针。在C ++中,这不会抛出异常。相反,它是未定义的行为。



没有像空指针异常,与Java将抛出空指针异常不同。相反,取消引用无效指针将导致未定义的行为。未定义的行为并不总是意味着崩溃,但是如果您的运行崩溃,您很幸运。



语言概述:



最后和RAII



C ++和Java之间最重要的区别之一是Java支持 finally 语句。无论上述 catch 块中的代码是否执行,始终运行 finally 块中的代码。例如:

  try 
{
}
catch(SomeException e)
{
}
finally
{
//这里的代码总是被激发出来。
}

finally语句的目的是允许程序员在此时进行清理,即释放套接字,关闭文件句柄等...即使Java运行垃圾收集器,垃圾回收仅适用于内存,也不适用于其他资源。还有一些情况下,您必须手动处理资源 。现在C ++没有一个终于语句,所以建议用户使用RAII原则(Resouce Acquisition is Initialization)Stroustrup在这里有一个解释: a href =http://www.stroustrup.com/bs_faq2.html#finally =nofollow noreferrer> http://www.stroustrup.com/bs_faq2.html#finally 。我更喜欢称它为$ code资源破坏是解除分配但基本上当你的对象超出范围时,调用析构函数,那么析构函数应该释放对象维护的任何资源。 >

例如,C ++ 11x提供了一个std :: unique_ptr来管理这个:

  void foo()
{
std :: unique_ptr< T> t(new T)
try
{
//使用t
}的代码
catch(...)
{
}
}

通过新分配的资源将在功能结束时被删除。



捕获所有语句



因为Java中的所有异常都继承自一个常见的基类异常如果你想要catch子句捕获任何异常,然后设置如下:

  catch(Exception e)
{
//抛出的任何异常都会在这里。
}

在C ++中,对于可以抛出的内容没有限制,没有常见的基类所有例外。标准做法是通过继承std :: exception来形成你的自定义异常类,但语言并不强制执行。相反,有一个特殊的语法来捕捉所有异常:

  catch(...)
{

}



未处理的异常



这是另一个语言行为不同的领域。在C ++中,一个抛出的未被捕获的异常将调用std :: terminate。 std :: terminate的默认行为是调用生成SIGABRT并且整个程序停止的abort。



在Java中,行为是打印堆栈跟踪并终止线程,未知的异常发生在。但是由于Java程序员可能会提供一个UncaughtException处理程序,这个行为可能会与默认终止线程不同。


In Java, if a specific line of code causes the program to crash, then the exception is caught and the program continues to execute.

However, in C++, if I have a piece of code that causes the program to crash, like:

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";
}

Then the program still crash and the exception is not caught.

So what is the point of exception handling in C++? Am I misunderstanding something?

解决方案

The line that crashes is dereferencing an invalid pointer. In C++ this will not throw an exception. Instead it is undefined behaviour.

There's no such thing as a null pointer exception in C++, unlike Java which will throw a null pointer exception. Instead dereferencing an invalid pointer will lead to undefined behaviour. Undefined behaviour does not always imply a crash, however if it crashes you're lucky.

Language overview:

Finally and RAII

One of the most significant differences bewtween C++ and Java is that Java supports a finally statement. Code in the finally block is always run regardless of whether code in the preceding catch block is executed or not. For example:

try
{
}
catch (SomeException e)
{
}
finally
{
  //code here is always exectued.
}

The purpose of the finally statement is to allow the programmer cleanup at that point, i.e. release sockets, close file handles etc... Even though Java runs a garbage collector, garbage collection only applies to memory and no other resource. There are still occasions where you have to manually dispose of resources. Now C++ doesn't have a finally statement so users of the language are advised to adhere to the RAII principle (Resouce Acquisition is Initialization) Stroustrup has an explanation about it here: http://www.stroustrup.com/bs_faq2.html#finally. I prefer to call it Resource destruction is deallocation but basically when your object falls out of scope, invoking the destructor, then that destructor should release whatever resources the object maintained.

For example, C++11x provides a std::unique_ptr to manage this:

void foo()
{
  std::unique_ptr<T> t(new T)
  try
  {
    //code that uses t
  }
  catch (...)
  {
  }
}

The resource allocated via new will be deleted when the function ends.

catch all statements

Because all exceptions in Java inherit from a common base class Exception if you want your catch clause to catch any exception, then set it up like this:

catch (Exception e)
{
  //any exception thrown will land here.
}

In C++ there's no restriction on what can be thrown and no common base class for all exceptions. Standard practice is to form your custom exception class by inheriting from std::exception but the language doesn't enforce this. Instead there's a special syntax for catching all exceptions:

catch (...)
{

}

Unhandled exceptions

This is another area where the languages behave differently. In C++ a thrown exception that is not caught will call std::terminate. std::terminate's default behaviour is to call abort which generates a SIGABRT and the entire program stops.

In Java the behaviour is to print a stack trace and terminate the thread that the uncaught exception occured in. However because a Java programmer may provide an UncaughtException handler, the behaviour could quite well be different from the default of terminating the thread.

这篇关于C ++和Java中异常处理的区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆