菜鸟学习C++-C++异常

来源:互联网 发布:淘宝上百丽运动旗舰店 编辑:程序博客网 时间:2024/04/29 23:42

背景:
第一次写技术博客,呵呵。自己对C++、linux比较感兴趣。虽然自己已经学习C++有三年,实际工作使用一年了,
但是还是感觉自己很薄弱,所以讲自己学习C++的学习历程写出来分享,和大家共同成长。
PS:所有的程序程序都是Vim编辑,在CentOS机器上运行。
好了,下面开始异常学习吧。


C++中异常的使用算是比较高级一点的东西,很多情况下可能我们并不是接触的太多。但是使用异常,可能增强系统
的健壮性,同时使程序更加简洁。
C++标准库使用throw来抛出异常,使用try-catch块来捕捉异常。和Java以及C#不同,它没有finally块。finally块
的意思是指,不论异常还是不异常,块里面的内容都要被执行,即使catch块里面包含return语句。这个特性感觉非常棒,
因为它让代码更简单。比如,有代码如下:
try
{


// 释放资源
}
catch()
{
// 释放资源
return -1;
}
因为代码中有释放资源的步骤存在,因此在try和catch中都要写这段代码,否则可能会造成内存泄漏。如果有了finally
块,那么我们把释放资源的代码放到finally中就可以了,只写一份代码。
try
{


}
catch()
{
return -1;
}
finally
{
// 释放资源
}
和标准C++不同,window的SHE机制是有finally的。


为了学习C++异常机制,自己写了个定制的异常类MyException,继承于exception。

    #ifndef _MYEXCEPTION_H__                                                                                                                                           

  2 #define _MYEXCEPTION_H__

  3 
  4 #include <exception>
  5 using namespace std;
  6 
  7 class MyException : public exception
  8 {
  9 public:  
 10     virtual const char * what() const throw();
 11 
 12 };
 13 
 14 
 15 #endif

  1 #include "myException.h"
  2 
  3 
  4 const char* MyException::what() const throw()                                                                                                                       
  5 {
  6     return "myException";
  7 }


  MyException类继承于exception类,因此需要覆盖父类what()方法。
  main.cpp文件

 1 #include <stdio.h>                                                                                                                                                  
  2 #include <exception>
  3 #include "myException.h"
  4 
  5 using namespace std;
  6 
  7 class A
  8 {  
  9 public:  
 10     A()
 11     {
 12         printf("A Constructor Called.\n");
 13     }
 14 
 15     ~A()
 16     {
 17         printf("A Deconstructor Called.\n");
 18     }
 19 
 20     void f() throw()
 21     {  
 22         throw MyException();
 23     }  
 24 };  
 25 
 26 
 27 
 28 int main(int argc, char **argv)
 29 {
 30 
 31     A a;  
 32     try
 33     {  
 34         a.f();  
 35     }
 36     catch(exception & exc)
 37     {  
 38         printf("%s\n", exc.what());
 39         return 0;
 40     }
 41 
 42     return 0;
 43 }

写好makefile,编译出可执行文件main。执行main发现结果和预期不同,输出如下:

A Constructor Called.
terminate called after throwing an instance of 'MyException'
  what():  myException
Aborted (core dumped)

程序core dump了,这是怎么回事呢。
翻看C++ primer,找到了答案。 main.cpp的20行,f()函数中声明会抛出异常,但是throw()里面要指明抛出的是何种异常。
否则,系统会认为是抛出异常类型为int型的。但是36行catch的是exception类型的,因此程序就会core掉。
改成如下:
void f() throw(MyException)
输出如下:

A Constructor Called.
myException
A Deconstructor Called.

正常了。
另外,注意catch的时候,异常类型是父类型的引用。涉及到动态绑定的内容。为何使用引用,而不是值传递,或者使用指针,
网上都有的讲,再次不赘述。


程序发生core之后,首先使用gdb进行调试。要想进行gdb调试,编译的时候g++要加上-g选项,这样才有调试信息,需要改造
makefile脚本。
另外,发生了core,还可以设置shell,使之产生core dump文件。然后使用gdb main core进行查看程序在哪发生core。

原创粉丝点击