20140801--异常类

1.异常类

#ifndef EXCEPTION_H_
#define EXCEPTION_H_ 

#include <string>
#include <exception>


class Exception : public std::exception
{
    public:
        Exception(const char *);
        Exception(const std::string &);
        virtual ~Exception() throw();  //这个函数不抛出异常
        virtual const char * what() const throw();
    private:
        std::string message_;  //异常名字
};


#endif  /*EXCEPTION_H_*/

#include "Exception.h"

Exception::Exception(const char *s)
    :message_(s)
{
}

Exception::Exception(const std::string &s)
    :message_(s)
{
}

Exception::~Exception() throw()
{
}

const char *Exception::what() const throw()
{
    return message_.c_str();
}

测试案例:

#include "Exception.h"

using namespace std;

int main(int argc, const char *argv[])
{
    throw Exception("hello world");
    return 0;
}

2.异常类升级版本exeption_stack

#ifndef EXCEPTION_H_
#define EXCEPTION_H_ 

#include <string>
#include <exception>

//编译时使用-rdynamic选项,确保stackTrace带有名字信息

class Exception : public std::exception
{
    public:
        Exception(const char *);
        Exception(const std::string &);
        virtual ~Exception() throw();  //这个函数不抛出异常
        virtual const char * what() const throw();
        const char *stackTrace() const throw(); 
    private:
        void fillStackTrace();  //填充栈痕迹

        std::string message_;  //异常名字
        std::string stack_;  //栈痕迹
};


#endif  /*EXCEPTION_H_*/

#include "Exception.h"
#include <stdlib.h>
#include <execinfo.h>

Exception::Exception(const char *s)
    :message_(s)
{
    fillStackTrace();
}

Exception::Exception(const std::string &s)
    :message_(s)
{
    fillStackTrace();
}

Exception::~Exception() throw()
{
}

const char *Exception::what() const throw()
{
    return message_.c_str();
}

void Exception::fillStackTrace()
{
    const int len = 200;
    void* buffer[len];
    //获取栈的调用痕迹 
    int nptrs = ::backtrace(buffer, len);
    //翻译成可读的字符串
    char** strings = ::backtrace_symbols(buffer, nptrs);
    if (strings)
    {
        for (int i = 0; i < nptrs; ++i)
        {
            // TODO demangle funcion name with abi::__cxa_demangle
            stack_.append(strings[i]);
            stack_.push_back('
');
        }
        free(strings);
    } 
}

const char *Exception::stackTrace() const throw()
{
    return stack_.c_str();
}

测试案例1

#include "Exception.h"
#include <stdio.h>
using namespace std;


//foobar
void foo()
{
    throw Exception("foobar"); 
}


void bar()
{
    foo();
}


int main(int argc, const char *argv[])
{
    try{
        bar();
    }
    catch(Exception &ex)
    {
        printf("reason: %s
", ex.what());
        printf("stack trace: %s
", ex.stackTrace());
    }
    return 0;
}

测试案例2:

#include <stdio.h>
#include "Exception.h"

class Bar
{
 public:
  void test()
  {
    throw Exception("oops");
  }
};

void foo()
{
  Bar b;
  b.test();
}

int main()
{
  try
  {
    foo();
  }
  catch (const Exception& ex)
  {
    printf("reason: %s
", ex.what());
    printf("stack trace: %s
", ex.stackTrace());
  }
}

ps:今天去人肉了下陈硕,发现这家伙真是个牛人。
参考:github.com/chenshuo

20130315-20140730-
原文地址:https://www.cnblogs.com/detectiveh/p/3885701.html