std::exception vs java.lang.Exception

106 篇文章 23 订阅
本文探讨了C++中的std::exception与Java中的java.lang.Exception之间的差异,特别是在构造函数方面的不同。由于这些差异,在从Java到C++进行代码转换时需要特别注意。
摘要由CSDN通过智能技术生成

我们知道std::exceptionjava.lang.Exception分别是C++和Java语言的大部分异常类型的基类。如果我们要定义一个自己的异常类型,一般会以这两个类做基类来写自己的类代码。这是我在写C++和Java代码的时的理解,觉得这俩货是一样的。
最近在研究Java到C++代码自动转换时(将项目中的一部分java代码自动翻译成C++代码),才发现在细节上这两个类还是有区别的。

下面是java中java.lang.Exception类的定义,
这里写图片描述
可以看到除了默认构造函数之外,还有另外三个构造函数。再看std::exception,在C++标准定义中除了默认构造函数外,只有一个构造函数。
这里写图片描述
http://www.cplusplus.com/reference/exception/exception/exception/
而实际gcc中对std::exception的定义就只有默认构造函数了(参见后面gcc的std::exception代码)

区别,这就是区别,所以在C++下 std::exception("hello")这样的写法是不对的,因为没有对应的构造函数。所以原本Java代码中throw new Exception("hello");这样的语句,就不能直接翻译成throw new std::exception("hello");

既然std::exception不能用来替代Java的java.lang.Exception,那么替代方案就是std::logic_error来替代java.lang.Exception

虽然不清楚为什么std::exception要做这样的定义,算不算个bug,但是使用起来确实很不方便啊。
大概microsoft发现了这个问题实在忍不了了,所以msvc中的std::exception就在标准C++基础上做了扩充,增加了exception(char const* const _Message)exception(exception const& _Other)构造函数(参见后面的代码)。

java中java.lang.Exception类代码

/*
 * %W% %E%
 *
 * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

package java.lang;

/**
 * The class <code>Exception</code> and its subclasses are a form of 
 * <code>Throwable</code> that indicates conditions that a reasonable 
 * application might want to catch.
 *
 * @author  Frank Yellin
 * @version %I%, %G%
 * @see     java.lang.Error
 * @since   JDK1.0
 */
public class Exception extends Throwable {
    static final long serialVersionUID = -3387516993124229948L;

    /**
     * Constructs a new exception with <code>null</code> as its detail message.
     * The cause is not initialized, and may subsequently be initialized by a
     * call to {@link #initCause}.
     */
    public Exception() {
	super();
    }

    /**
     * Constructs a new exception with the specified detail message.  The
     * cause is not initialized, and may subsequently be initialized by
     * a call to {@link #initCause}.
     *
     * @param   message   the detail message. The detail message is saved for 
     *          later retrieval by the {@link #getMessage()} method.
     */
    public Exception(String message) {
	super(message);
    }

    /**
     * Constructs a new exception with the specified detail message and
     * cause.  <p>Note that the detail message associated with
     * <code>cause</code> is <i>not</i> automatically incorporated in
     * this exception's detail message.
     *
     * @param  message the detail message (which is saved for later retrieval
     *         by the {@link #getMessage()} method).
     * @param  cause the cause (which is saved for later retrieval by the
     *         {@link #getCause()} method).  (A <tt>null</tt> value is
     *         permitted, and indicates that the cause is nonexistent or
     *         unknown.)
     * @since  1.4
     */
    public Exception(String message, Throwable cause) {
        super(message, cause);
    }

    /**
     * Constructs a new exception with the specified cause and a detail
     * message of <tt>(cause==null ? null : cause.toString())</tt> (which
     * typically contains the class and detail message of <tt>cause</tt>).
     * This constructor is useful for exceptions that are little more than
     * wrappers for other throwables (for example, {@link
     * java.security.PrivilegedActionException}).
     *
     * @param  cause the cause (which is saved for later retrieval by the
     *         {@link #getCause()} method).  (A <tt>null</tt> value is
     *         permitted, and indicates that the cause is nonexistent or
     *         unknown.)
     * @since  1.4
     */
    public Exception(Throwable cause) {
        super(cause);
    }
}

gcc中std::exception的代码

  /**
   *  @brief Base class for all library exceptions.
   *
   *  This is the base class for all exceptions thrown by the standard
   *  library, and by certain language expressions.  You are free to derive
   *  your own %exception classes, or use a different hierarchy, or to
   *  throw non-class data (e.g., fundamental types).
   */
  class exception
  {
  public:
    exception() _GLIBCXX_USE_NOEXCEPT { }
    virtual ~exception() _GLIBCXX_USE_NOEXCEPT;

    /** Returns a C-style character string describing the general cause
     *  of the current error.  */
    virtual const char* what() const _GLIBCXX_USE_NOEXCEPT;
  };

msvc中std::exception的代码

class exception
{
public:

    exception() throw()
        : _Data()
    {
    }

    explicit exception(char const* const _Message) throw()
        : _Data()
    {
        __std_exception_data _InitData = { _Message, true };
        __std_exception_copy(&_InitData, &_Data);
    }

    exception(char const* const _Message, int) throw()
        : _Data()
    {
        _Data._What = _Message;
    }

    exception(exception const& _Other) throw()
        : _Data()
    {
        __std_exception_copy(&_Other._Data, &_Data);
    }

    exception& operator=(exception const& _Other) throw()
    {
        if (this == &_Other)
        {
            return *this;
        }

        __std_exception_destroy(&_Data);
        __std_exception_copy(&_Other._Data, &_Data);
        return *this;
    }

    virtual ~exception() throw()
    {
        __std_exception_destroy(&_Data);
    }

    virtual char const* what() const
    {
        return _Data._What ? _Data._What : "Unknown exception";
    }

private:

    __std_exception_data _Data;
};
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

10km

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值