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