【问题标题】:How to add an error logger to a class如何将错误记录器添加到类
【发布时间】:2010-10-14 05:21:44
【问题描述】:

我想使用一个通用的错误消息处理程序,这样我就可以轻松地为任何类使用GetLastErrorSetError。我想出了这个方案。但我有几个问题。请注意,此实现仅用于测试。但我想把基本设计做好。

#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;
    }
}
  1. 我可以在子类中覆盖这个函数吗? virtual void SetError(const char* zFormat, ...)
  2. 我可以取消RecordingErrors 类吗?我觉得MyClass 必须从ErrorHandler 继承,我认为这不好。我是对还是错?这是关于组合而不是继承的另一个问题。编辑:我指的不是名字,而是想法?
  3. 这种方法会失败的任何可能情况?
  4. 有没有更好的方法来实现错误日志记录?(这里的日志记录不是正确的词。它是什么)

【问题讨论】:

标签: c++ logging


【解决方案1】:

错误处理程序和记录器是两个不同的实体。错误处理程序决定如何处理错误。应该立即发送到记录器,应该保存在数据库中,还是应该简单地保存在某个缓冲区中直到有人询问。
记录器决定如何记录给定的消息。它应该显示在控制台上还是应该保存在磁盘文件中,应该以什么格式显示。

请记住记录器的功能。
1)它应该是独立的类。它的行为不应依赖于其他类。
2)记录器最可取的应该是单例。你不需要很多漂浮的物体做同样的事情。但是当涉及到多线程时,单例类也有自己的头疼问题。所以我知道这一点值得商榷。
3)它必须并且必须具有异步日志记录的能力。这意味着生产者和消费者的实现。 (日志记录是一种 i/o 操作,因此本质上很昂贵。您不希望主处理为此而占用。但是,您可能又不想使用线程来废弃这个。)

在您执行错误记录器时,我看不到任何记录器。此外,您的错误处理程序正在保存一个错误。您可能需要错误向量。使用固定参数保持 SetError。传递错误 ID、错误消息和错误缓冲区长度等参数。让调用者创建错误消息。

【讨论】:

  • 与我的问题不相关:(虽然你的指针很好。正如我在问题中提到的那样,我想不出正确的措辞。我只想要最后一个错误。就像getlasterror()
  • 我终于意识到你是对的。 :)。我的问题是我试图同时处理错误处理和错误记录。
  • +1 非常有用的信息。调用堆栈也可能有用,有时项目需要它。使用异步日志记录(启用缓冲),它必须决定是否将消息刷新到 I/O。如果不刷新,紧随其后的严重错误可能不会在日志中留下任何消息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-13
  • 1970-01-01
  • 2021-02-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多