2012-05-08 4 views
1

Donc, j'ai une classe de base:Pourquoi ne pas surcharger cette méthode de classe de base?

enum ComparableType 
{ 
    CompType_ShaderObject 
}; 

class Comparable 
{ 
public: 
    Comparable(void) {}; 
    Comparable(ComparableType ct) : mComparableType(ct) 
    {} 
    inline virtual std::string& getKey(void) = 0; 
    virtual ComparableType getType(void) = 0; 
protected: 
    virtual ~Comparable(void){ } ; 
protected: 
    virtual bool operator>(const Comparable& isLessThan) = 0; 
    virtual bool operator<(const Comparable& isGreaterThan) = 0; 
    virtual bool operator>=(const Comparable& isLessThanOrEqualTo) = 0; 
    virtual bool operator<=(const Comparable& isGreaterThanOrEqualTo) = 0; 
    virtual bool operator==(const Comparable& isEqualTo) = 0; 
    virtual bool operator!=(const Comparable& isNotEqualTo) = 0; 

protected: 
    ComparableType mComparableType; 

}; 

qui agit comme une base pour les éléments suivants:

class ShaderComparable : public Comparable, public std::string 
    { 
    public: 
     ShaderComparable(void) { }; 
     ShaderComparable(const char* shaderFilename); 
     ~ShaderComparable(void); 

    public: 
     inline std::string& getKey(void) { return mFilename; } 
     inline ComparableType getType(void) { return mComparableType; } 

    public: 
     virtual bool operator>(const ShaderComparable& isLessThan); 
     virtual bool operator<(const ShaderComparable& isGreaterThan); 
     virtual bool operator>=(const ShaderComparable& isLessThanOrEqualTo); 
     virtual bool operator<=(const ShaderComparable& isGreaterThanOrEqualTo); 
     virtual bool operator==(const ShaderComparable& isEqualTo); 
     virtual bool operator!=(const ShaderComparable& isNotEqualTo); 
    private: 
     inline bool isSameType(const ShaderComparable& objectToCheck) { return mComparableType == CompType_ShaderObject; } 
     std::string mFilename; 
    }; 

Le seul problème est que, pour une raison quelconque, je suis incapable de surcharger le L'opérateur fonctionne à partir de la classe de base pour accepter le type ShaderComparable, par opposition à Comparable. Y a-t-il un moyen de contourner ceci?

Mes erreurs sont les suivantes:

>c:\programming\c++\git\escalator\engine\engine\shadercomparable.cpp(26): error C2653: 'ShaderComparable' : is not a class or namespace name 
1>c:\programming\c++\git\escalator\engine\engine\shadercomparable.cpp(26): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int 
1>c:\programming\c++\git\escalator\engine\engine\shadercomparable.cpp(26): error C2143: syntax error : missing ',' before '&' 
1>c:\programming\c++\git\escalator\engine\engine\shadercomparable.cpp(33): error C2653: 'ShaderComparable' : is not a class or namespace name 
1>c:\programming\c++\git\escalator\engine\engine\shadercomparable.cpp(33): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int 
1>c:\programming\c++\git\escalator\engine\engine\shadercomparable.cpp(33): error C2143: syntax error : missing ',' before '&' 
1>c:\programming\c++\git\escalator\engine\engine\shadercomparable.cpp(39): error C2653: 'ShaderComparable' : is not a class or namespace name 
1>c:\programming\c++\git\escalator\engine\engine\shadercomparable.cpp(39): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int 
1>c:\programming\c++\git\escalator\engine\engine\shadercomparable.cpp(39): error C2143: syntax error : missing ',' before '&' 
1>c:\programming\c++\git\escalator\engine\engine\shadercomparable.cpp(44): error C2653: 'ShaderComparable' : is not a class or namespace name 
1>c:\programming\c++\git\escalator\engine\engine\shadercomparable.cpp(44): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int 
1>c:\programming\c++\git\escalator\engine\engine\shadercomparable.cpp(44): error C2143: syntax error : missing ',' before '&' 
1>c:\programming\c++\git\escalator\engine\engine\shadercomparable.cpp(49): error C2653: 'ShaderComparable' : is not a class or namespace name 
1>c:\programming\c++\git\escalator\engine\engine\shadercomparable.cpp(49): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int 
1>c:\programming\c++\git\escalator\engine\engine\shadercomparable.cpp(49): error C2143: syntax error : missing ',' before '&' 

Mise à jour

est le fichier source Ici il vient:

ShaderComparable::ShaderComparable(const char* shaderFilename) 
     : Comparable(CompType_ShaderObject), 
      mFilename(shaderFilename) 
    {} 

    ShaderComparable::~ShaderComparable(void) 
    { 
    } 

    bool ShaderComparable::operator>(const ShaderComparable& isLessThan) 
    { 
     std::string toCompare = std::string(); 

     if(toCompare.compare(mFilename) > 0) 
      return true; 
     else 
      return false; 
     } 
    } 

    bool ShaderComparable::operator<(const ShaderComparable& isGreaterThan) 
    { 

     std::string toCompare = std::string(); 
     return true; 
    } 

    bool ShaderComparable::operator>=(const ShaderComparable& isLessThanOrEqualTo) 
    { 

     return false; 
    } 

    bool ShaderComparable::operator<=(const ShaderComparable& isGreaterThanOrEqualTo) 
    { 
     return false; 
    } 

    bool ShaderComparable::operator==(const ShaderComparable& isEqualTo) 
    { 
     return false; 
    } 

    bool ShaderComparable::operator!=(const ShaderComparable& isNotEqualTo) 
    { 
     return false; 
    } 
+1

compile très bien - http://ideone.com/vse9u –

+0

Deux choses ... les signatures de fonction de vos opérateurs de comparaison ne correspondent pas entre la base et classes dérivées. Cela se traduira par des choses ne fonctionnent pas comme prévu. Deuxièmement, ne dérivez pas des conteneurs de bibliothèque standard (std :: string dans ce cas). Leurs destructeurs ne sont pas virtuels, donc votre classe dérivée fuira quand ils sont détruits. – luke

+0

@luke non, c'est UB. Vous ne savez pas qu'ils vont fuir. –

Répondre

1

Le seul problème est que, pour une raison quelconque, je suis incapable de surcharger les fonctions de l'opérateur de la classe de base pour accepter le type de ShaderComparable, par opposition juste comparable. Y at-il un moyen de contourner cela?

Vous ne pouvez pas "surcharger" les fonctions virtuelles de cette façon. La classe dérivée (ou l'une de ses sous-classes) doit implémenter toutes les fonctions virtuelles pures, et cela nécessite que les arguments correspondent exactement.

Ce que vous pouvez faire est d'utiliser dynamic_cast:

struct A 
{ 
    virtual void foo(A&) = 0; 
}; 

struct B : public A 
{ 
    virtual void foo(A& myA) 
    { 
     try 
     { 
      B& myB = dynamic_cast<B&>(myA); // dynamic_cast is what you want, but be aware it has runtime overhead 
      // do something 'B' specific, with myB 
     } 
     catch (const std::bad_cast& e) 
     { 
      std::cerr << e.what() << std::endl; 
      std::cerr << "This object is not of type B" << std::endl; 
     } 
    } 
}; 
+0

S'il contrôle à la fois la classe 'Comparable' de base et les choses qui en découlent, cela pourrait aussi être un candidat pour une double distribution – tmpearce

1

Lorsque vous implémentez overrider finale, la liste des paramètres doit être identique à la classe de base. Le vôtre ne l'est pas. Voici un exemple simplifié:

class Base 
{ 
public: 
    virtual Base& foo(const Base& obj) = 0; 
}; 

class Der : public Base 
{ 
public: 
    void Base& foo(const Der& obj) 
    { 
     return * this; 
    }; 
}; 

int main() { 
    Base* p = new Der; 

    return 0; 

} 

Ce code est pas légal car Der::foo() prend une référence Der comme paramètre, pas une référence Base. C'est légal:

class Der : public Base 
{ 
public: 
    void Base& foo(const Base& obj) 
    { 
     return * this; 
    }; 
}; 

En aparté, même si la liste des paramètres doit être identique à la déclaration de classe de base, le type de retour ne doit pas être identique. Il doit cependant être co-variant. Donc, c'est aussi juridique:

class Der : public Base 
{ 
public: 
    void Der& foo(const Base& obj) 
    { 
     return * this; 
    }; 
}; 
Questions connexes