2010-06-24 14 views
-1

Je veux faire ce qui suit:C++ hérite d'une classe de base virtal

class ErrorBase 
{ 
    public: 
    void SetError(unsigned errorCode) 
    { 
     mErrorCode = errorCode; 
    } 

    char const* Explanation(unsigned errorCode) const 
    { 
     return errorExplanations[errorCode]; 
    } 

    private: 
    char const* errorExplanations[]; 
    unsigned mErrorCode; 

}; 

class MyError : virtual public ErrorBase 
{ 
    public: 
    enum ErrorCodes { 
     eNone, 
     eGeneric, 
     eMySpecificError 
    }; 

    MyError() 
    { 

     // I want this to refer to the parent class's attribute, 
     // such that when Explanation() is executed, it uses this 
     errorExplanations = { 
     "no error", 
     "error in MyClass", 
     "specific error" 
     } 
    } 
    ~MyError() { } 
}; 

Mais je reçois l'erreur suivante sur la ligne déclarant errorExplanations dans la classe des enfants:

error: expected primary-expression before '{' token

Comment puis-je déclarer errorExplanations dans la classe enfant de telle sorte que je peux instancier un enfant, et appeler myChild.Explanation() et obtenir l'une des chaînes d'erreur définies dans le constructeur de l'enfant?

Toutes les suggestions/corrections concernant mon utilisation de const, virtual, public, etc sont appréciés, Merci!

+0

sans rapport avec l'héritage virtuel –

Répondre

2

Soit vous passer le tableau des messages d'erreur à la classe de base dans son constructeur (syntaxe ne peut pas être parfait, mais nous espérons que vous avez l'idée):

class ErrorBase { 
    public: 
    ErrorBase(char const* errorExplanations[]) { 
     this->errorExplanations = errorExplanations; 
    } 
    ... 
    private: 
    char const* errorExplanations[]; 
    ... 
}; 

class MyError : virtual public ErrorBase { 
    public: 
    ... 
    MyError() : 
     ErrorBase({ 
     "no error", 
     "error in MyClass", 
     "specific error" 
     }) 
    { } 
    ... 
}; 

Ou vous faire Explanation virtuel et fournir la mise en œuvre souhaitée dans la classe dérivée:

class ErrorBase { 
    public: 
    ... 
    virtual char const* Explanation(unsigned errorCode) const = 0; 
    protected: 
    unsigned mErrorCode; 
}; 

class MyError : virtual public ErrorBase { 
    public: 
    ... 
    MyError() : 
     errorExplanations({ 
     "no error", 
     "error in MyClass", 
     "specific error" 
     }) 
    { } 

    virtual char const* Explanation(unsigned errorCode) const { 
     return errorExplanations[errorCode]; 
    } 
    ... 
    private: 
    char const* errorExplanations[]; 
}; 
+0

J'ai fini par utiliser la première option, merci pour la réponse! – aaronstacy

2

Eh bien, une chose qui ne va pas, c'est que vous ne pouvez pas affecter à des tableaux comme ça. Vous ne pouvez les initialiser que de cette manière. Puisque vous avez déjà initialisé le tableau (pour être vide) dans la section d'initialisation du constructeur (qui, bien que vide, utilise des constructeurs par défaut), votre tableau est initialisé.

Vous devrez affecter au tableau de l'une des manières habituelles d'assigner des tableaux, tels que memcpy ou une boucle for.

Une autre chose qui ne va pas, c'est que vous n'avez pas accès au tableau dans lequel vous essayez de l'assigner. Vous devrez l'exposer aux sous-classes avec protégé ou avoir une fonction d'affectation.

0

Essayez quelque chose comme:

class ErrorBase 
{ 
    public: 
    void SetError(unsigned errorCode) 
    { 
     mErrorCode = errorCode; 
    } 

    char const* Explanation(unsigned errorCode) const 
    { 
     return errorExplanations[errorCode]; 
    } 

    private: 
    char const** errorExplanations; 
    unsigned mErrorCode; 

}; 

class MyError : virtual public ErrorBase 
{ 
    public: 
    enum ErrorCodes { 
     eNone, 
     eGeneric, 
     eMySpecificError 
    }; 

    char const* child_strings[] = {"no error", "error in MyClass", "specific error"}; 

    MyError() 
    { 

     // I want this to refer to the parent class's attribute, 
     // such that when Explanation() is executed, it uses this 
     errorExplanations = child_strings; 
    } 
    ~MyError() { } 
}; 

Demandez à votre classe parent ne contiennent que un pointeur, demandez à votre classe enfant à créer et initialiser le tableau, puis faire le point de pointeur sur le tableau dans le constructeur de votre enfant.

2

Voici une autre option. Ont la classe de base obtenir le tableau de données via une fonction virtuelle:

class ErrorBase 
{ 
    public: 
    void SetError(unsigned errorCode) 
    { 
     mErrorCode = errorCode; 
    } 

    char const* Explanation(unsigned errorCode) const 
    { 
     return GetErrorTable()[errorCode]; 
    } 

    private: 
    virtual char const **GetErrorTable() const = 0; 

    private: 
    unsigned mErrorCode; 

}; 

class MyError : virtual public ErrorBase 
{ 
    virtual char const **GetErrorTable() 
    { 
     static char const *data[] = { 
     "no error", 
     "error in MyClass", 
     "specific error" 
     }; 
     return data; 
    } 
}; 
0

Une autre option: faire la fonction Explanation(unsigned) constvirtual afin que les classes dérivées à gérer leur propre mécanisme pour rechercher des messages d'erreur:

class ErrorBase 
{ 
public: 
    virtual ~ErrorBase() { } 

    void SetError(unsigned errorCode) 
     : mErrorCode(errorCode) 
    { 
    } 

    char const* Explanation() const { return this->Explanation(mErrorCode); } 

    virtual char const* Explanation(unsigned errorCode) const 
    { 
     return errorExplanations[errorCode]; 
    } 

private: 
    unsigned mErrorCode; 
}; 

class MyError : virtual public ErrorBase 
{ 
public: 
    enum ErrorCode { 
     eNone = 0, 
     eGeneric = 1, 
     eMySpecificError = 2 
    }; 

    MyError(ErrorCode c) 
     : ErrorBase(static_cast<unsigned>(c)) 
    { 
    } 

    virtual ~MyError() { } 

    virtual char const* Explanation(unsigned errorCode) const; 
}; 

Le chaînes d'erreur pour MyError codes d'erreur sont ensuite compilées dans un fichier objet:

// MyError.cpp 
static const char* s_errorExplanations[] = { 
     "no error", 
     "error in MyClass", 
     "specific error" 
    }; 

char const* MyError::Explanation(unsigned errorCode) const 
{ 
    return s_errorExplanations[errorCode]; 
}