纯虚函数和抽象类

时间:2010-07-06 11:58:27

标签: c++ abstract-class pure-virtual

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

有人可以告诉我如何解决此错误吗?

我猜这是因为并非两个纯虚函数都没有在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 singleton

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

2 个答案:

答案 0 :(得分:2)

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

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

你可能在logDLog的第一次重载中意味着这一点:

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

编辑:您还没有实现

的重载
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”const-correct。

答案 1 :(得分:1)

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