背景:好久之前的代码。用于在一些特定环境下辅助调试。
想调试代码,但又不想在release版本当中生产任何实际的代码,于是我写了如下的头文件:
调试时还是有点方便的,呵呵。
// DBG_HELPER.H
// [4/14/2010]
// 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 _UNICODE
typedef std::wstring tstring;
typedef std::wostringstream tostringstream;
typedef std::wostream tostream;
typedef std::wofstream tofstream;
typedef std::wstringstream tstringstream;
#define tcout std::wcout
#else
typedef std::string tstring;
typedef std::ostringstream tostringstream;
typedef std::stringstream tstringstream;
typedef std::ostream tostream;
typedef std::ofstream tofstream;
#define tcout std::cout
#endif
namespace dbg{
class single_threaded
{
public:
single_threaded(){}
virtual ~single_threaded(){}
virtual void lock(){}
virtual void unlock(){}
private:
};
#ifdef WIN32
class multi_threaded
{
public:
multi_threaded(){
#ifdef _DEBUG
static bool isinitialised = false;
if (!isinitialised) {
InitializeCriticalSection(get_critsec());
isinitialised = true;
}
#endif
}
multi_threaded(const multi_threaded &) {;}
virtual ~multi_threaded(){}
virtual void lock() {
#ifdef _DEBUG
EnterCriticalSection(get_critsec());
#endif
}
virtual void unlock() {
#ifdef _DEBUG
LeaveCriticalSection(get_critsec());
#endif
}
private:
#ifdef _DEBUG
CRITICAL_SECTION *get_critsec()
{
static CRITICAL_SECTION g_critsec;
return &g_critsec;
}
#endif
};
#endif // end of WIN32
template<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 _DEBUG
class dbg2file_global;
class dbg2file
{
public:
dbg2file(const TCHAR *szFile, std::ios::openmode mode=std::ios::out)
{
// vc6 下UNICODE版本有问题,因为vc6的fstream中open不支持wchar_t
ostr_.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 version
class 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
分享到:
相关推荐
33位大师,每个人对代码之美都 有自己独特的认识,现在一览无余的放在一起,对于热爱程序的每个人都不啻一场盛宴。 虽然本书的涉猎范围很广,但也只能代表一小部分在这个软件开发这个最令人兴奋领域所发生的事情。 ...
值得一提的是,其中有些方法已经被网络犯罪分子广泛应用到恶意软件之中了。 对于JavaScript来说,你只需要花一点时间进行调试和分析,你就能够了解到JavaScript代码段的功能逻辑。而我们所要讨论的内容,可以给那些...
例程是用多种语言写成的,因为对于程序员来说,掌握多种语言是其必不可少的基本素质之一。而且,只有掌握了不受语法规则限制的编程准则,才能真正有效地提高你的编程效率和质量。 为了减轻由于使用多种语言所带来的...
对于Angular新手来说,调试Angular需要一个过程,并在这个过程中不断积累经验,一看到报错,就能八九不离十猜出问题出在什么地方。 这篇文章,我们先来从常见的Angular调试技巧讲起,如果遇到404 (not found)报错...
现在编写这种带数据层的代码,已经比较有经验了。 2012年2月2日11:18:37 即使是很简单的功能,也可能需要长时间的编写。积累就因此非常的重要。 而且有一点,我一定不要忘记,那就是我现在所编写的代码,都是高层的...
经验表明,日志记录往往是软件开发周期中的重要组成部分。它具有以下几个优点:它可以提供应用程序运行时的精确环境,可供开发人员尽快找到应用程序中的Bug;一旦在程序中加入了Log 输出代码,程序运行过程中就能...
在学习编程语言时,环境、代码调试等,都是很多读者最头疼的地方,而且很多代码都会存在一些细节上的问题,所以,《Java开发实战经典(名师讲坛)》为了让读者可以更好地理解每一个知识点,将书中所有内容都录制成了...
本书尤其适合作为你的引路书籍,因为它翔实地介绍了初学者入门时所必需的知识积累,而这些知识在《操作系统:设计与实现》一书中是没有涉及的,笔者本人是把这本书作为写操作系统的主要参考书籍之一,所以在本书中对...
本书尤其适合作为你的引路书籍,因为它翔实地介绍了初学者入门时所必需的知识积累,而这些知识在《操作系统:设计与实现》一书中是没有涉及的,笔者本人是把这本书作为写操作系统的主要参考书籍之一,所以在本书中对...
Linux操作系统作为目前最流行的开源操作系统之一,在嵌入式系统中得到了广泛的应用。然而,在将Linux内核移植到嵌入式硬件平台的过程中,经常会遇到各种问题,其中一些是纯软件问题,有些是软件和硬件接口的问题。在...
由于Android构建在开源代码的框架之上,而且提供了强大的SDK库和开放的理念,所以它为广大的没有任何移动应用程序开发经验的新手开辟了一条开发完美的移动应用程序的康庄大道。而富有经验的移动开发人员现在也可以...
在学习编程语言时,环境、代码调试等,都是很多读者最头疼的地方,而且很多代码都会存在一些细节上的问题,所以,本书为了让读者可以更好地理解每一个知识点,将书中所有内容都录制成了视频,让每一位读者真正做到...
在学习编程语言时,环境、代码调试等,都是很多读者最头疼的地方,而且很多代码都会存在一些细节上的问题,所以,本书为了让读者可以更好地理解每一个知识点,将书中所有内容都录制成了视频,让每一位读者真正做到...
在学习编程语言时,环境、代码调试等,都是很多读者最头疼的地方,而且很多代码都会存在一些细节上的问题,所以,本书为了让读者可以更好地理解每一个知识点,将书中所有内容都录制成了视频,让每一位读者真正做到...
在学习编程语言时,环境、代码调试等,都是很多读者最头疼的地方,而且很多代码都会存在一些细节上的问题,所以,本书为了让读者可以更好地理解每一个知识点,将书中所有内容都录制成了视频,让每一位读者真正做到...
在学习编程语言时,环境、代码调试等,都是很多读者最头疼的地方,而且很多代码都会存在一些细节上的问题,所以,本书为了让读者可以更好地理解每一个知识点,将书中所有内容都录制成了视频,让每一位读者真正做到...
这很正常 – 这只是编程者必须做的事之一。实际上,按照大量的研究,程序员平均百分之五十的时间花在解决代码中的错误。 关键是学会怎样有效地调试你的程序。我有一些技巧可以帮助你解决程序为什么没有象应该的那样...
Ivor Horton是撰著Java、C和C++编程语言图书的杰出作家之一。大家一致认为,他的著作独具风格,无论是编程新手,还是经验丰富的编程人员,都很容易理解其内容。在个人实践中,Ivor Horton也是一名系统顾问。他从事...
PC-Lint是C/C++软件代码静态分析工具,你可以把它看作是一种更加严格的编译器。它不仅可以检查出一般的语法错误,还可以检查出那些虽然符合语法要求但不易发现的潜在错误。 C语言的灵活性带来了代码效率的提升,但...
, 在学习编程语言时,环境、代码调试等,都是很多读者最头疼的地方,而且很多代码都会存在一些细节上的问题,所以,《Java开发实战经典(名师讲坛)》为了让读者可以更好地理解每一个知识点,将书中所有内容都录制成了...