чисто виртуальная функция и абстрактный класс - PullRequest
1 голос
/ 06 июля 2010

У меня есть следующие классы, 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 экземпляр как одиночный

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

Ответы [ 2 ]

2 голосов
/ 06 июля 2010
virtual void log(string logText, int debugLevel, string threadName = "") = 0;

не реализовано в классе DLog.Вы должны реализовать это, потому что это чисто виртуальный в базовом классе.

Вы, вероятно, имели в виду это при первой перегрузке log в DLog:

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-правильным во-первых.

1 голос
/ 06 июля 2010

Получая класс DLog из Logger, вы гарантируете, что обеспечите реализацию для всех (при условии, что вы не хотите DLog в качестве абстрактного класса) чисто виртуальных методов, объявленных в базовом классе.Здесь вы не предоставили реализацию чисто виртуальных функций, поэтому класс DLog становится абстрактным классом.В C ++ вы не можете создать экземпляр абстрактного класса, следовательно, вы получаете ошибку компилятора.Кстати, в вашем базовом классе отсутствует виртуальный деструктор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...