qinchong637 发表于 2013-2-7 04:45:08

代码调试经验之一

背景:好久之前的代码。用于在一些特定环境下辅助调试。
想调试代码,但又不想在release版本当中生产任何实际的代码,于是我写了如下的头文件:
调试时还是有点方便的,呵呵。
// DBG_HELPER.H//// BY qinchong637#gmail.com//////////////////////////////////////////////////////////////////////////// 描述://   使用<<输出信息到控制台、文件、调试器。// 设计目标://   本文件中的功能仅仅在_DEBUG下才有实际作用,在release版本下无任何作用//   本文件中各种类、函数的release版本经过编译器优化后,无任何实际代码生成// // _DBG_PROMPT : 当前代码行所在的文件和行号// dbg2console : 将信息输出到控制台// dbg2debugger : 将信息输出到调试器,目前仅在Windows下有效。// dbg2file : 将信息输出到文件// dbg2file_global : dbg2file的全局变量版本(然而并非线程安全,建议在程序初始化时就定义一个该类别的变量),这里采用的方法有待改进// 注意://   1、在release版本中使用dbg2file_global会出现警告,是因为重载()时返回了一个临时变量的引用,//   通常这会有潜在的危险,但这里可以忽略掉,编译器进行优化时这段代码会被去掉,不会生成任何实际的代码//   2、输出指针所指对象时,需使用static_cast,否则会出现运行时错误,原因未明。如:dbg2file()<<*pInt; => dbg2file()<<static_cast<int>(*pInt);//////////////////////////////////////////////////////////////////////////#pragma once#ifndef _DBG_HELPER_H_QC637_FSEYE_HOTMAIL_528#define _DBG_HELPER_H_QC637_FSEYE_HOTMAIL_528#include <iostream>#include <fstream>#include <string>#include <sstream>#include <tchar.h>#ifdef WIN32#include <windows.h>#endif#ifdef DBG_DEFAULT_MT_POLICY#pragma message("*** DBG_HELPER.H : Another DBG_DEFAULT_MT_POLICY defined anywhere alse and this maybe cause an error***")#else#ifdef _DBG_SINGLE_THREADED#define DBG_DEFAULT_MT_POLICY single_threaded#else#define DBG_DEFAULT_MT_POLICY multi_threaded#endif#endif#define _DBG_FILE_VERSION _T("1.0.0")#ifdef _DBG_PROMPT#pragma message("*** DBG_HELPER.H : Another _DBG_PROMPT defined anywhere else and this maybe cause a an error***")#else#define _DBG_PROMPT __FILE__##<<_T(": ")<<__LINE__<<_T(": ")#endif// 有关UNICODE 的定义#if defined _UNICODEtypedef std::wstringtstring;typedef std::wostringstreamtostringstream;typedef std::wostreamtostream;typedef std::wofstreamtofstream;typedef std::wstringstreamtstringstream;#define tcoutstd::wcout#elsetypedef std::stringtstring;typedef std::ostringstreamtostringstream;typedef std::stringstreamtstringstream;typedef std::ostreamtostream;typedef std::ofstreamtofstream;#definetcoutstd::cout#endifnamespace dbg{class single_threaded{public:single_threaded(){}virtual ~single_threaded(){}virtual void lock(){}virtual void unlock(){}private:};#ifdef WIN32class multi_threaded{public:multi_threaded(){#ifdef _DEBUGstatic bool isinitialised = false;if (!isinitialised) {InitializeCriticalSection(get_critsec());isinitialised = true;}#endif}multi_threaded(const multi_threaded &) {;}virtual ~multi_threaded(){}virtual void lock() {#ifdef _DEBUGEnterCriticalSection(get_critsec());#endif}virtual void unlock() {#ifdef _DEBUGLeaveCriticalSection(get_critsec());#endif}private:#ifdef _DEBUGCRITICAL_SECTION *get_critsec(){static CRITICAL_SECTION g_critsec;return &g_critsec;}#endif};#endif// end of WIN32template<class mt_policy=DBG_DEFAULT_MT_POLICY>class glock_dbg : public mt_policy{};template<class mt_policy=DBG_DEFAULT_MT_POLICY>class lock_block : public mt_policy{public:lock_block() {this->lock();}~lock_block() {this->unlock();}};// class dbg2console {};class dbg2debugger{};#ifdef _DEBUGclass dbg2file_global;class dbg2file {public:dbg2file(const TCHAR *szFile, std::ios::openmode mode=std::ios::out) {// vc6 下UNICODE版本有问题,因为vc6的fstream中open不支持wchar_tostr_.open(szFile, mode);}~dbg2file() {if (ostr_.is_open()) {ostr_.close();}}public:tofstream ostr_;private:dbg2file() {}void open(const TCHAR *szFile, std::ios::openmode mode=std::ios::out){ostr_.open(szFile, mode);}friend class dbg2file_global;};class dbg2file_global{public:dbg2file_global(const TCHAR *szFile, std::ios::openmode mode=std::ios::out) {static bool isinitialised = false;if (!isinitialised) {getInst().open(szFile, mode);isinitialised = true;}}~dbg2file_global() {}dbg2file &operator()(){return getInst();}private:static dbg2file& getInst(){static dbg2file ostr_;return ostr_;}};template<typename T>inline dbg2file & operator <<(dbg2file &out, const T &obj){out.ostr_<<obj;return out;}template<typename T>inline dbg2console & operator <<(dbg2console &out, const T &obj){tcout<<obj;return out;}template<typename T>inline dbg2debugger & operator <<(dbg2debugger &out, const T &obj){tstringstream strs;strs<<obj;tstring str = strs.str();OutputDebugString(str.c_str());return out;}#else// RELEASE VERSION// Take the same interface as in the DEBUG versionclass dbg2file {public:dbg2file(const TCHAR *szFile, std::ios::openmode mode=std::ios::out|std::ios::app) {}~dbg2file() {}};class dbg2file_global{public:dbg2file_global(const TCHAR *szFile, std::ios::openmode mode=std::ios::out) {}~dbg2file_global() {}// have a warning here. but no problems.dbg2file &operator()(){return dbg2file(NULL, 0);}private:};template<typename T>inline dbg2file & operator <<(dbg2file &out, const T &obj){return out;}template<typename T>inline dbg2console & operator <<(dbg2console &out, const T &obj){return out;}template<typename T>inline dbg2debugger & operator <<(dbg2debugger &out, const T &obj){return out;}#endif // end of release version}#endif// end of file
页: [1]
查看完整版本: 代码调试经验之一