POCO C++库学习和分析 -- 异常、错误处理、调试 (五)

2014-11-24 03:15:31 · 作者: · 浏览: 4
。宏定义如下:
[cpp]
#define poco_ndc(func) \
Poco::NDCScope _theNdcScope(#func, __LINE__, __FILE__)

#if defined(_DEBUG)
#define poco_ndc_dbg(func) \
Poco::NDCScope _theNdcScope(#func, __LINE__, __FILE__)
#else
#define poco_ndc_dbg(func)
#endif

#define poco_ndc(func) \
Poco::NDCScope _theNdcScope(#func, __LINE__, __FILE__)

#if defined(_DEBUG)
#define poco_ndc_dbg(func) \
Poco::NDCScope _theNdcScope(#func, __LINE__, __FILE__)
#else
#define poco_ndc_dbg(func)
#endif

NDCScope实现了诊断信息上下文的入栈出栈工作,它通过调用NestedDiagnosticContext类的静态函数current实现了此功能。其定义如下:


[cpp]
inline NDCScope::NDCScope(const std::string& info)
{
NestedDiagnosticContext::current().push(info);
}

inline NDCScope::NDCScope(const std::string& info, int line, const char* filename)
{
NestedDiagnosticContext::current().push(info, line, filename);
}

inline NDCScope::~NDCScope()
{
NestedDiagnosticContext::current().pop();
}

inline NDCScope::NDCScope(const std::string& info)
{
NestedDiagnosticContext::current().push(info);
}

inline NDCScope::NDCScope(const std::string& info, int line, const char* filename)
{
NestedDiagnosticContext::current().push(info, line, filename);
}

inline NDCScope::~NDCScope()
{
NestedDiagnosticContext::current().pop();
}

NestedDiagnosticContext类的current()是个静态函数,其定义如下:


[cpp]
namespace
{
static ThreadLocal ndc;
}

NestedDiagnosticContext& NestedDiagnosticContext::current()
{
return ndc.get();
}

namespace
{
static ThreadLocal ndc;
}

NestedDiagnosticContext& NestedDiagnosticContext::current()
{
return ndc.get();
}


而ThreadLocal是一个辅助类,用于获取线程对象的本地存储信息或者是主线程的本地存储信息。


[cpp]
template
class ThreadLocal
/// This template is used to declare type safe thread
/// local variables. It can basically be used like
/// a smart pointer class with the special feature
/// that it references a different object
/// in every thread. The underlying object will
/// be created when it is referenced for the first
/// time.
/// See the NestedDiagnosticContext class for an
/// example how to use this template.
/// Every thread only has access to its own
/// thread local data. There is no way for a thread
/// to access another thread's local data.
{
typedef TLSSlot Slot;

public:
ThreadLocal()
{
}

~ThreadLocal()
{
}

C* operator -> ()
{
return &get();
}

C& operator * ()
/// "Dereferences" the smart pointer and returns a reference
/// to the underlying data object. The reference can be used
/// to modify the object.
{
return get();
}

C& get()
/// Returns a reference to the underlying data object.
/// The reference can be used to modify the object.
{
TLSAbstractSlot*& p = ThreadLocalStorage::current().get(this);
if (!p) p = new Slot;
return static_cast(p)->value();
}

private:
ThreadLocal(const ThreadLocal&);
ThreadLocal& operator = (const ThreadLocal&);
};

template
class ThreadLocal
/// This template is used to declare type safe thread
/// local variables. It can basically be used like
/// a smart pointer class with the special feature
/// that it references a different object
/// in every thread. The underlying object will