c++ surcharger Surcharges de fonctions membres héritées




surcharger operator c++ (3)

Une classe peut-elle surcharger des méthodes qui existent également dans l'interface héritée du public? Il semble que ce soit sans ambiguïté et utile, mais les compilateurs (VC, Intel, GCC) se plaignent tous, au moins par ma construction. Voici un exemple de jouet. La fonction héritée rebound () a deux surcharges claires, mais cela ne compilera pas. Si vous renommez la méthode rebound () dans l'une ou l'autre classe, cela fonctionne bien, mais s'ils partagent le même nom de fonction membre (même s'ils sont surchargés avec des types d'arguments différents!), Vous obtenez une erreur fatale appel."

La solution de contournement est triviale (je vais simplement renommer les méthodes) mais j'essaie simplement de comprendre s'il s'agit d'une restriction C ++ (et pourquoi elle le serait).


#include 
class Bound {
public:
  Bound() : x0(0.0), x1(0.0) {};
  Bound(double x) : x0(x), x1(x) {};
  double width() const {return x1-x0;}
  void rebound(const Bound *a, const Bound *b);
private:
  double x0, x1;
};

void Bound::rebound(const Bound *a, const Bound *b)
{
  if (a && b) {
    x0=std::min(a->x0, b->x0);
    x1=std::max(a->x1, b->x1);
  }
}

class Node : public Bound {
public:
  Node(double x) : Bound(x), left(0), right(0) {};
  Node(Node *a, Node *b) : left(a), right(b) {rebound();}
  void rebound() { rebound(left, right); }
private:
  Node *left;
  Node *right;
};


int main() {
  Node A(1.0);
  Node B(2.0);
  Node C(&A, &B);
}

Vous pouvez faire trois choses:

1. Afficher la méthode de la classe de base

Ajoutez une using dans la déclaration de Node :

using Bound::rebound;
void rebound() { rebound(left, right); }

2. Se référer explicitement à la méthode de la classe de base

Utilisez l'espace de noms lié:

void rebound() { Bound::rebound(left, right); }

3. Définir / redéfinir toutes les surcharges dans la classe dérivée

Déléguez l'implémentation à la classe de base (si cela est fait dans l'en-tête, il ne devrait pas y avoir de pénalité due à l'inline):

void rebound(const Bound *a, const Bound *b) { Bound::rebound(a, b); };
void rebound() { rebound(left, right); }

Plus d'infos: https://isocpp.org/wiki/faq/strange-inheritance#overload-derived


Lorsque vous déclarez une méthode dans la sous-classe avec le même nom mais une signature différente, elle cache la version du parent.

Vous pouvez vous y référer spécifiquement comme Bound :: rebound (...) ou utiliser le mot-clé using.

Voir ici






overloading