设为首页 加入收藏

TOP

C++异常(二)
2017-08-10 10:22:40 】 浏览:7910
Tags:异常

c++ try–catch的语句原型如下:

try
{
//程序中抛出异常
throw value;
}
catch(valuetype v)
{
//例外处理程序段
}

C++的异常中,程序接受到throw语句后就会自动调用析构器,把该域(try所在的大括号内)对象clean up,然后再进入catch语句(如果在循环体中就退出循环)。
这种机制会引起一些致命的错误,比如,当“类”有指针成员变量时(又是指针!),在 “类的构建器”中的throw语句引起的退出,会导致这个指针所指向的对象没有被析构。
比如:

class A{
public:
    A(){
        t = new char[100]; //malloc in A()
        delete this; //delete object that has been defined,this program mean delete obj a
        throw 0;
    }
    ~A(){ delete[] t}
};
//因为在构造函数中抛出异常,所以无法调用析构函数,t无法释放,new出来的100字节变成内存垃圾
int func(){
    A a;
    A *p = new A();
    delete p;
    return 0;
}

所以我们可以通过把指针改为类就行了,比如模板类来代替指针,在模板类的内部设置一个析构函数。来解决问题。

如果抛出的是一个指针:

try{
    throw new Y();
}catch(Y* p){
    //whoops,forgot to delete..
    //must delete p in this catch
}

所以,更好的一种处理方式是,抛出的异常是堆栈里面的对象,catch的时候做一个引用。

struct A{
    virtual void print(){...}
};
struct B: public A{....};

try{
    throw B("B error");
}catch(A& a){
    a.print();
}

C++中,如果有这样的函数:

void f(int x):throw(exception type1){
...
}

那么,在C++(在运行的时候处理异常)中,意味着在f()函数中,在运行的时候,f()函数最多只能抛出一个异常,而且是type1类型的。如果在函数f()中,抛出了别的异常,那么会有一个unexcepted异常抛出,去告诉函数f(),抛出了不是type1类型的异常。所以C++函数后面的throw是约束函数f()的:

void f():throw(){...} //函数f()不抛出任何异常,如果抛出,则unexcepted异常抛出 void f(){...} //函数f()可以抛出任何异常 void f():throw(T){...} //函数f()抛出T类型或T子类异常

而在Java中异常是在编译的时候处理的,如果是上面这样的函数,则是提示调用f()的时候,需要对type1的异常做出处理。也就是在try–catch中有针对type1的处理。(约束调用函数f()的调用者)
- void f():throw(){...} //函数f()抛出任何异常,如果抛出
- void f(){...} //函数f()不抛出任何异常
- void f():throw(T){...} //函数f()抛出T类型或T子类异常

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇C++的封装、继承、多态 下一篇C/C++实现strcpy和strcat两个功能

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目