C++ 异常使用总结(持续更新)

C++ 异常使用总结

 

一、注意在构造函数中的异常

如构造函数中抛出异常的,C++的异常机制是不会去调用它的析构函数的。这个问题会造成一些内存泄露的问题。

看一下这个例子:

class CSpace
{
public:
    CSpace()
    {
        m_pSpace = newint[100];
        //
        throw 1;
    }
    ~CSpace()
    {
        deletem_pSpace;
    }
private:
    int *m_pSpace;
    //...
public:
    //...
};
void Render()
{
    try
    {
        CSpace space;
        //....
    }
    catch(CException* e)
    {
    }
}
 

这里CSpace的构造函数在位m_pSpace申请完空间后,抛出异常,那么在Render函数进行异常处理。这个时候因为系统认为CSpace对象还没构造好,就不去调用它的析构函数。所以麻烦来了,谁去处理m_pSpace呢?这个成为了有一个被遗弃的指针,永远不会被释放。

还好这个问题完全可以从设计上去解决。

我们可以使用Init和Release之类的函数。还是直接看代码。

class CSpace
{
public:
    CSpace()
    {
       
        m_pSpace = NULL;
    }
    ~CSpace()
    {
    }
private:
    int *m_pSpace;
    //...
public:
    void Init()
    {
        m_pSpace = newint[100];
    }
    voidRelease()
    {
        deletem_pSpace;
        m_pSpace = NULL;
    }
    //...
};

原本来说构造函数就只是负责一些变量的赋初值工作


二、捕获异常的类型

抛出捕获的异常,应该用什么类型比较好。看了一些资料,还是感觉引用是最不错的。

这里应该也就三种情况:

1.     catch(Exceptionex) ,这个主要是每次catch都要拷贝一次,这个提高了catch的代价;

2.     catch(Exception* ex),这个最大缺陷,也是指针的通病,你要怎么去处理这个异常指针,要不要delete这个指针;

主要是要试想一下,如果这个异常对象是存在于堆里的话,你在这里delete掉,肯能导致其它地方再次使用时,会带来很大的麻烦。

3.     catch(Exception& ex),这个既解决了拷贝的代价,也不必再去考虑释放异常对象。

上面三种情况,就知道使用引用处理异常的捕获是最好的选择。


三、MFC中的CException

这个是比较麻烦,因为这里catch的类型都是指针型的,需要你自己去调用CException中的Delete函数来进行释放。

当然用TRY CATCH宏的话,就不用手动去调用Delete函数了。


 

四、VisualStudio中的编译选项

在Vs中如果选择/EHa编译选项的话,可以用catch捕获到一些不是throw的异常,甚至连Access violations也能捕获到。可以看官网中的介绍


会持续更新,如果有了新发现……


 

 

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页