异常类

/* MyException.h*/

#ifndef EXCEPTION_TEST_H_
#define EXCEPTION_TEST_H_

#include <exception>
#include <string>

#define MY_THROW(ExClass,args...)   \
        do\
        {\
            ExClass e(args);   \
            e.Init(__FILE__,__PRETTY_FUNCTION__,__LINE__); \
            throw e; \
        }while(false)

#define MY_DEFINE_EXCEPTION(ExClass,Base)  \
        ExClass(const std::string& msg="") throw()  \
                :Base(msg)   \
        {}  \
        ~ExClass() throw(){}  \
        std::string GetClassName() const  \
        { \
            return #ExClass;  \
        }

class ExceptionBase:public std::exception
{
public:
    ExceptionBase(const std::string& msg="")throw();
    virtual ~ExceptionBase() throw();
    void Init(const char *file,const char* func,int line);
    virtual std::string GetClassName() const;
    virtual std::string GetMessage() const;
    const char* what() const throw();
    const std::string* ToString() const;
    std::string GetStackTrace() const;
protected:
    std::string  mMsg;
    const char*  mFile;
    const char*  mFunc;
    int          mLine;
private:
    enum{MAX_STACK_TRACE_SIZE=50};
    void* mStackTrace[MAX_STACK_TRACE_SIZE];
    size_t  mStackTraceSize;
    mutable std::string  mWhat;
};

class ExceptionDerived:public ExceptionBase
{
public:
    MY_DEFINE_EXCEPTION(ExceptionDerived,ExceptionBase);
};

#endif                  

/MyException.cpp /

#include <execinfo.h>
#include <stdlib.h>
#include <cxxabi.h>
#include <iostream>
#include <sstream>

#include "MyException.h"

using namespace std;

ExceptionBase::ExceptionBase(const string& msg) throw()
    :mMsg(msg),
    mFile("<unknow file>"),
    mFunc("<unknow func>"),
    mLine(-1),
    mStackTraceSize(0)
{
}

ExceptionBase::~ExceptionBase() throw()
{}

void ExceptionBase::Init(const char* file,const char* func,int line)
{
    mFile=file;
    mFunc=func;
    mLine=line;
    m_StackTraceSize=backtrace(mStackTrace,MAX_STACK_TRACE_SIZE);
}

string ExceptionBase::GetClassName() const
{
    return "ExceptionBase";
}

const char* ExceptionBase::what() const throw()
{
    return ToString().c_str();
}

const string& ExceptionBase::ToString() cosnt
{
    if(mWhat.empty())
    {
        stringstream sstr("");
        if(mLine>0)
        {
            sstr<<mFile<<"("<<mLine<<")";
        }
        sstr<<":"<<GetClassName();
        if(!GetMessage().empty())
        {
                sstr<<":"<<GetMessage();
        }
        sstr<<"\nStack Trace:\n";
        sstr<<GetStackTrace();
        mWhat=sstr.str();
    }
    return mWhat;
}

string ExceptionBase::GetMessage()const
{
    return mMsg;
}

string ExceptionBase::GetStackTrace() cosnt
{
    if(mStackTraceSize==0)
            return "<No Stack Trace\n";
    char** strings=backtrace_symbols(mStackTrace,10);
    if(strings==NULL)
        return "<Unknow error:backtrace_symbols returned null>\n";
    string result;
    for(size_t i=0;i<mStackTraceSize;++i)
    {
            string mangledName=strings[i];
            string::size_type begin=mangledName.find('(');
            string::size_type end=mangledName.find('+',begin);
            if(begin==string::npos||end==string::npos)
            {
                result+=mangledName;
                result+='\n';
                continue;
            }
            ++begin;
            int status;
            char* s=abi::__cxa_demangle(mangledName.substr(begin,end-begin).c_str(),NULL,0,&status);
            if(status!=0)
            {
                result+=mangledName;
                result+='\n';
                continue;
            }
            string demangledName(s);
            free(s);
            result+=mangledName.substr(0,begin);
            result+=demangledName;
            result+=mangledName.substr(end);
            result+='\n';
    }
    free(strings);
    return result;
}

/test/

#include "MyException.h"
#include <iostream>

using namespace std;
int f2()
{
    MY_THROW(ExceptionDerived,"f2 throw");
}

void f1()
{
    try{
        f2();
    }
    catch(ExceptionDerived& e)
    {
            cout<<e.what()<<endl;
    }
}

int main()
{
    f1();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值