背景:
第一次写技术博客,呵呵。自己对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。
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。
第一次写技术博客,呵呵。自己对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__
34 #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。