纯虚函数和抽象类

发布于 2024-09-08 19:22:24 字数 1263 浏览 2 评论 0原文

我有以下类,Base 和 Derived,当我编译时,编译器抱怨它无法创建 DLog 的实例,因为它是抽象的。

有人可以告诉我如何修复这个错误吗?

我猜这是因为并非两个纯虚函数都没有在派生中实现。

class Logger
{
public:

    virtual void log(int debugLevel, char* fmt, ...) = 0;
    virtual void log(string logText, int debugLevel, string threadName = "") = 0;

    static Logger* defaultLogger() {return m_defaultLogger;}
    static void setDefaultLogger(Logger& logger) {m_defaultLogger = &logger;}

protected:

    static Logger* m_defaultLogger;
};

class DLog : public Logger
{
public:
    DLog();
    ~DLog();

    static DLog *Instance();
    static void Destroy();

    void SetLogFilename(std::string filename);
    void SetOutputDebug(bool enable);
    std::string getKeyTypeName(long lKeyType);
    std::string getScopeTypeName(long lScopeType);
    std::string getMethodName(long lMethod);

    virtual void log(string logText, int debugLevel)
    {
        Log(const_cast<char*>(logText.c_str()));
    }

    void Log(char* fmt, ...);

private:

    static DLog *m_instance;

    std::string m_filename;
    bool m_bOutputDebug;
};

// DLog 实例作为单例

DLog *DLog::Instance()
{
    if (!m_instance)
        m_instance = new DLog();
    return m_instance;
}

I have the following classes, Base and Derived and when I compile the compiler complains that it cannot create an instance of DLog because it is abstract.

Can someone tell me how I can fix this error?

I'm guessing it's because not both pure virtual functions are not implemented in the Derived.

class Logger
{
public:

    virtual void log(int debugLevel, char* fmt, ...) = 0;
    virtual void log(string logText, int debugLevel, string threadName = "") = 0;

    static Logger* defaultLogger() {return m_defaultLogger;}
    static void setDefaultLogger(Logger& logger) {m_defaultLogger = &logger;}

protected:

    static Logger* m_defaultLogger;
};

class DLog : public Logger
{
public:
    DLog();
    ~DLog();

    static DLog *Instance();
    static void Destroy();

    void SetLogFilename(std::string filename);
    void SetOutputDebug(bool enable);
    std::string getKeyTypeName(long lKeyType);
    std::string getScopeTypeName(long lScopeType);
    std::string getMethodName(long lMethod);

    virtual void log(string logText, int debugLevel)
    {
        Log(const_cast<char*>(logText.c_str()));
    }

    void Log(char* fmt, ...);

private:

    static DLog *m_instance;

    std::string m_filename;
    bool m_bOutputDebug;
};

// DLog instantion as a singleton

DLog *DLog::Instance()
{
    if (!m_instance)
        m_instance = new DLog();
    return m_instance;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

落花浅忆 2024-09-15 19:22:25
virtual void log(string logText, int debugLevel, string threadName = "") = 0;

尚未在 DLog 类中实现。您必须实现它,因为它在基类中是纯虚拟的。

您可能在 DLog 中第一次重载 log 时表示这一点:

virtual void log(string logText, int debugLevel, string /*threadname*/)
{
    Log(const_cast<char*>(logText.c_str()));
}

您也没有在这里实现 Note 的重载

virtual void log(int debugLevel, char* fmt, ...) = 0;

编辑:尽管使用 const_cast 是一个非常糟糕的主意,并且是未定义的行为。您可以通过执行以下操作来获得明确定义的行为:

virtual void log(string logText, int debugLevel, string /*threadname*/)
{
    logText.push_back('\0'); // Add null terminator
    Log(&logText[0]); // Send non-const string to function
    logText.pop_back(); // Remove null terminator
}

不过更好的是,首先使“Log”常量正确。

virtual void log(string logText, int debugLevel, string threadName = "") = 0;

has not been implemented in class DLog. You have to implement it because it's pure virtual in the base class.

You probably meant this in your first overload of log in DLog:

virtual void log(string logText, int debugLevel, string /*threadname*/)
{
    Log(const_cast<char*>(logText.c_str()));
}

EDIT: You also have not implemented the overload of

virtual void log(int debugLevel, char* fmt, ...) = 0;

Note here though that using the const_cast is a very bad idea and is undefined behavior. You can get well defined behavior by doing something like this instead:

virtual void log(string logText, int debugLevel, string /*threadname*/)
{
    logText.push_back('\0'); // Add null terminator
    Log(&logText[0]); // Send non-const string to function
    logText.pop_back(); // Remove null terminator
}

Better yet though, just make "Log" const-correct in the first place.

情愿 2024-09-15 19:22:25

通过从 Logger 派生您的 DLog 类,您可以确保为所有内容提供实现(假设您不希望将 DLog 作为抽象)类)在基类中声明的纯虚方法。这里您没有提供纯虚函数的实现,因此类 DLog 成为一个抽象类。在 C++ 中,您无法创建抽象类的实例,因此会出现编译器错误。顺便说一句,您的基类缺少虚拟析构函数。

By deriving your DLog class from Logger you are assuring that you will provide the implementation for all (assuming you don't want DLog as an abstract class) pure virtual methods declared in the base class. Here you have not provided implementation to pure virtual functions hence class DLog becomes an abstract class. In C++ you can not create an instance of an abstract class hence you get the compiler error. BTW, your base class is missing the virtual destructor.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文