我想使用通用错误消息处理程序,因此我可以轻松地为任何类GetLastError
和SetError
。我提出了这个计划。但我有几个问题。请注意,此实现仅用于测试。但我想让基本设计正确。
#include <iostream>
#include <stdarg.h>
class ErrorHandler
{
public:
virtual void SetError(const char* zFormat, ...)
{
va_list args;
va_start (args, zFormat);
vsnprintf (z_ErrorBuf, sz_MaxBufSize, zFormat, args);
va_end (args);
}
const char* GetError() const
{
return z_ErrorBuf;
}
virtual ~ErrorHandler(){}
explicit ErrorHandler(const size_t szMaxBufSize = 1024)
{
z_ErrorBuf = malloc(sizeof(char)*szMaxBufSize);
sz_MaxBufSize = szMaxBufSize;
}
void ResizeBuffer(const size_t szMaxBufSize)
{
z_ErrorBuf = realloc(z_ErrorBuf, szMaxBufSize);
sz_MaxBufSize = szMaxBufSize;
}
protected:
char* z_ErrorBuf;
size_t sz_MaxBufSize;
};
class MyClass;
//Worker can be just an interface if needed. So, can't use friend.
class Worker
{
public:
void Work(MyClass& oGod);
};
void Worker::Work(MyClass& oGod)
{
//Work
//OnError
oGod.GetErrorHandler().SetError("Save me %s", "not");
}
class RecordingErrors
{
public:
const char* GetLastError() const
{
return oErrorHandler.GetError();
}
//GetErrorHandler is public
ErrorHandler& GetErrorHandler()
{
return oErrorHandler;
}
private:
ErrorHandler oErrorHandler;
};
class MyClass : public RecordingErrors
{
public:
bool GetThingsDone(Worker& me)
{
me.Work(*this);
//on Error
return false;
}
};
int main()
{
MyClass oL;
Worker w;
if(!oL.GetThingsDone(w))
{
std::cout << oL.GetLastError() << std::endl;
}
}
virtual void SetError(const char* zFormat, ...)
。RecordingErrors
课吗?我觉得那么MyClass
必须继承ErrorHandler
我认为不好的{{1}}。我是对还是错?这是关于继承的构成的另一个问题。编辑:我不是指名字,而是想法?答案 0 :(得分:3)
错误处理程序和记录程序是两个不同的实体。错误处理程序决定如何处理错误。它应该立即发送到记录器,是否应保存在数据库中,还是应该保存在某个缓冲区中,直到有人要求。
记录器决定如何记录给定的消息。它应该显示在控制台上还是应保存在磁盘文件中,应以何种格式显示。
请记住记录仪的功能 1)它应该是独立的类。它的行为不应该依赖于其他类别 2)记录器最优选应该是单例。你不需要在做同样事情的周围漂浮很多物体。但是,当涉及多线程时,单例类有其自身的麻烦。所以我知道这一点值得商榷 3)它必须且必须具有异步日志记录的功能。这意味着生产者和消费者实施。 (记录是一种i / o操作,因此本质上是昂贵的。你不希望你的主要处理过程。但是你可能不想再使用线程来废弃这个。)
在执行错误记录器时,我看不到任何记录器。您的错误处理程序也会保存一个错误。您可能需要错误向量。使用固定参数保留SetError。传递参数,如错误ID,错误消息和错误缓冲区长度。让调用者创建错误消息。