2017-03-14 5 views
3

Je suis nouveau à C++ et essayer d'écrire une interface comme ci-dessous:C++ d'appel de méthode (de lvalue) se liant à la fonction (rvalue) à la place classe dérivée de la fonction (lvalue) dans la classe de base

template <class T> 
class Comparable 
{ 
    protected: 
     Comparable(){}; 
    public: 
     virtual int compare(const T&&)=0; 
     int compare(const T& o) 
     { 
     return this->compare(std::move(o)); 
     } 
}; 

Je l'ai ceci pour essayer de faire fonctionner la méthode de comparaison avec les deux valeurs l/r. I dérivé de la classe de Comparable suivante: Méthode

class Monkey : Comparable<Monkey> 
{ 
    private: 
     char name[512]; 
    public: 
     Monkey(const char*&& name) 
     { 
     strcpy(this->name, name); 
     } 
     const char *getName() { return name; } 
     int compare(const Monkey&& m) 
     { 
     return strcmp(name, m.name); 
     } 
}; 

avec la main() comme suit:

Monkey m1(argv[1]), m2(argv[2]); 
printf("\"%s\" \"%s\" %d\n", m1.getName(), m2.getName(), m2.compare(m1)); 

Mais je reçois une erreur de compilation:

ne peut pas lier « Tests :: Singe 'lvalue to' const Tests :: Monkey & & ' initialise l'argument 1 de' virtual int Tests :: Monkey :: compare (const Tests :: Monkey & &) ' Échec de la construction

Pourquoi l'appel de méthode ne lie-il pas la méthode de comparaison dans la classe de base? Lorsque je les crée à la fois en tant que virtuel dans la classe de base et les écris tous les deux dans la classe dérivée, la liaison fonctionne correctement, mais cela ne fonctionne pas et j'obtiens une erreur de compilation si je tente de la compiler. ici.

+0

Je ne vois vraiment pas pourquoi vous utilisez des références rvalue partout. La const-référence normale pour la fonction 'compare' fonctionnerait très bien. Et en passant une référence rvalue à 'const char *'? Cela n'a vraiment pas beaucoup de sens. Enfin, les références rvalue constantes n'ont souvent aucun sens non plus. –

+0

je suis nouveau en C++. Je pense que les références empêchent la copie, qui est le comportement par défaut des appels de fonction, donc j'ai pensé que cela pourrait être une bonne habitude de prendre l'habitude de les utiliser et de s'y habituer. Et j'ai déjà vu des références const. Bien que l'impact de la performance est probablement négligeable. –

+0

@JoePaul Reference introduit [overhead] (http://stackoverflow.com/questions/8250932/what-is-the-overhead-of-passing-a-reference) aussi. La référence de lvalue de const fera le perferect dans votre cas. La référence rvalue est principalement utilisée pour l'acheminement parfait et la sémantique de déplacement. – felix

Répondre

3

Ceci est un nom qui se cache; nom dans la classe dérivée cache le nom dans la classe de base. En bref, vous ne pouvez pas surcharger les fonctions à travers différentes portées.

Selon la règle de unqualified name lookup, pour m2.compare(m1), m2 est de type Monkey, le nom compare se trouve à la portée de la classe dérivée Monkey tout d'abord, puis nommez des arrêts de recherche. Les compare s de la classe de base ne seront pas pris en compte pour la résolution de surcharge suivante.

(Souligné par)

For an unqualified name, that is a name that does not appear to the right of a scope resolution operator ::, name lookup examines the scopes as described below, until it finds at least one declaration of any kind, at which time the lookup stops and no further scopes are examined.

Vous pouvez présenter les noms de classe de base dans le cadre de la classe dérivée par using:

class Monkey : Comparable<Monkey> 
{ 
     ... 

     using Comparable<Monkey>::compare; 
     int compare(const Monkey&& m) 
     { 
     return strcmp(name, m.name); 
     } 
}; 
+0

merci. cela a répondu à ma question. –