2017-07-09 3 views
0

J'ai une classe BinaryMemoryReader qui a une fonction définie comme ceci:Surcharger une fonction avec une fonction d'une autre classe

template <typename T> 
inline void read(T **data) { 
    *data = (T*)&stream[position]; 
    position += sizeof(T); 
} 

Il gère la plupart des types standard d'un flux en mémoire.

Les types personnalisés complexes ont lu les fonctions de leur propre, telles que:

void AnotherClass::read(BinaryMemoryReader *const reader) 
{ 
    reader->read<bool>(&num); 
    reader->read<short>(&count); 
} 

Ce que je voudrais écrire est le code qui, quand j'écris

reader->read<AnotherClass>(&var); 

appelleraient la deuxième fonction. Cela signifierait que la fonction de lecture de AnotherClass surchargerait la fonction de lecture BinaryMemoryReader pour ce type particulier.

Cela me permettrait d'écrire un code beaucoup plus propre.

EDIT: L'idée générale est la suivante:

  1. ont une classe BinaryMemoryReader centrale.
  2. Avoir une fonction de lecture générique pour gérer les types standard.
  3. Avoir la syntaxe pour l'appeler soit bmr->read<int>(&intVar);
  4. Avoir des fonctions de lecture spécialisées définies dans leurs propres classes.
  5. Plus important encore, la syntaxe de les appeler serait bmr->read<customType>(&customTypeVar);

De cette façon, les fonctions de lecture spécifiques seraient associés à leurs propres classes, mais aurait pu être appelé à partir du BinaryMemoryReader.

+0

Google "Spécialisation de modèle C++". – LogicStuff

+1

Notez que chacune des fonctions de lecteur supplémentaires sont définies dans leurs propres classes, et non dans 'BinaryMemoryReader'. – Karlovsky120

+1

Pourquoi ne pas créer une fonction de modèle libre, qui prend un paramètre 'BinaryMemoryReader' et un' T'? Celui-ci pourrait être facilement spécialisé dans n'importe quel autre module de classe. – user0042

Répondre

1

Comme je l'ai écrit dans mon commentaire que je voudrais utiliser l'approche suivante:

  1. ont une fonction libre basé sur un modèle

    template <typename T> 
    void read(BinaryMemoryReader& bmr, T& data) { 
        bmr.read(&data); 
    } 
    
  2. Spécialiser cette fonction pour chacun des types que vous voulez gérer

    class AnotherClass { 
        template <typename T> 
        friend void read(BinaryMemoryReader& bmr, T &data); 
    
        bool num; 
        short count; 
    }; 
    
    template <> 
    void read(BinaryMemoryReader& bmr, AnotherClass &data) { 
        bmr.read<bool>(&(data.datanum)); 
        bmr.read<short>(&(data.count)); 
    }; 
    
  3. Appel comme

    BinaryMemoryReader bmr; 
    AnotherType at; 
    read(bmr,at); 
    

Cette technique est utilisée par exemple avec le C++ bibliothèque d'E/S standard et prévu pour les surcharges

std::ostream& operator<<(std::ostream&, const T&); 
std::istream& operator>>(std::istream&, T&); 

fonctions.


Vous pouvez également effectuer cette spécialisation pour la fonction BinaryMemoryReader::read().Mais BinaryMemoryReader doit être friend de toutes les spécialisations de classe.

+0

Je n'aime pas faire cela dans l'espace de noms global. Y a-t-il moyen de limiter cela à la classe 'BinaryMemoryReader' et aux types qui implémentent les lecteurs spécifiques? Même si cela signifie écrire un peu plus du code standard? – Karlovsky120

+0

@ Karlovsky120 Bien sûr, vous devriez le faire en utilisant un espace de noms spécifique. La spécialisation de la fonction 'BinaryMemoryReader :: read()' fonctionnerait aussi bien avec IMO. – user0042

+0

Ce que je veux dire c'est que je n'aime pas faire cela en dehors des cours. Tout en gardant le code dans l'autre classe? Je ne sais pas comment utiliser les délégués, mais pourraient-ils être mis en œuvre ici? – Karlovsky120