2010-07-06 7 views
1

J'ai les classes suivantes, Base et Derived et quand je compile le compilateur se plaint qu'il ne peut pas créer une instance de DLog parce qu'il est abstrait. Est-ce que quelqu'un peut me dire comment je peux corriger cette erreur?fonction virtuelle pure et classe abstraite

Je suppose que c'est parce que les deux fonctions virtuelles pures ne sont pas implémentées dans le dérivé.

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 comme un singleton

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

Vous devez implémenter les PVF dans la classe dérivée, évidemment. –

+1

S'il vous plaît s'il vous plaît s'il vous plaît, ne pas surcharger les fonctions avec une ellipse. Vous épargnera des heures de tiraillement et de débogage tard le soir. –

+0

@Alex: Pas une surcharge ... c'est avec un L majuscule la fonction Log. les autres sont en minuscules ... –

Répondre

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

n'a pas été mis en œuvre en classe Dlog. Vous devez l'implémenter car c'est purement virtuel dans la classe de base.

Vous vouliez probablement dire dans votre première surcharge de log en DLog:

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

EDIT: Vous avez également pas mis en œuvre la surcharge de

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

Notez ici si que l'utilisation du const_cast est un très mauvaise idée et est un comportement indéfini. Vous pouvez obtenir un comportement bien défini en faisant quelque chose comme ceci:

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 
} 

Mieux encore bien, il suffit de faire const-correct « Connexion » en premier lieu.

+0

Je pensais que la chaîne était nulle terminée? Ou est-ce juste un char * thats null terminé? –

+1

@Tony: Certaines implémentations de 'std :: string' auront un terminateur nul, mais elles ne sont pas obligatoires, sauf si vous appelez le membre' c_str'. Cependant, vous ne pouvez pas modifier le tampon renvoyé par 'c_str' et avoir un comportement bien défini. –

1

En dérivant votre DLog classe de Logger vous assurer que vous fournirez la mise en œuvre pour tous (en supposant que vous ne voulez pas DLog comme une classe abstraite) des méthodes virtuelles pures déclarées dans la classe de base. Ici, vous n'avez pas fourni d'implémentation aux fonctions virtuelles pures donc la classe DLog devient une classe abstraite. En C++, vous ne pouvez pas créer une instance d'une classe abstraite, vous obtenez donc l'erreur du compilateur. BTW, votre classe de base manque le destructeur virtuel.

Questions connexes