std::exception标准和各平台实现的不同

C++98标准:

C++11标准:

g++ 5.4.0实现如下:

VS2015实现如下:

可见,g++只是实现了标准中的默认构造函数;而VS扩展了标准,新增了explicit exception(char const* const _Message) throw()和exception(char const* const _Message, int) throw();即像throw std::exception("Invalid input.");这种用法VS中可用,g++就不行了。

补充一下:

throw和throw new的区别

  1. throw exception()表示编译器会自动建立一个异常对象,并且由编译器负责清理对象所占内存

  2. throw new exception()表示抛出一个由用户建立的异常对象的指针,并且在catch子句中声明为exception *,需要由用户自己处理异常对象的内存。

建议使用throw exception()

析构函数中不能抛出异常

  1. 如果析构函数抛出异常,则异常点之后的程序不会执行,如果析构函数在异常点之后执行了某些必要的动作比如释放某些资源,则这些动作不会执行,会造成诸如资源泄漏的问题。
  2. 通常异常发生时,c++的机制会调用已经构造对象的析构函数来释放资源,此时若析构函数本身也抛出异常,则前一个异常尚未处理,又有新的异常,会造成程序崩溃的问题。
  3. 析构函数的异常不能被抛出析构函数之外,需要在析构函数内部进行处理。

throw抛出的对象

如果throw抛出一个对象,那么无论catch中用什么类型接收(引用或其他),在传递到catch之前都会构造一个临时对象,也就是说至少经历了一次对象的复制,因此要求异常类型必须可复制的,并且该临时对象的类型与异常对象的静态类型是一致的,也就是说,如果throw抛出的是一个指向子类对象的父类引用,那么会发生分割现象,即只有子类对象中的父类部分会被抛出,抛出对象的类型也是父类类型。(从实现上讲,是因为复制到“临时对象”的时候,使用的是throw语句中类型的(这里是父类的)复制构造函数)。 

原文地址:https://www.cnblogs.com/a3192048/p/12241326.html