Un operateur c'est une fonction comme une autre.
Si tu as:
A* a;
B* b;
et que tu fais:
a->f(b); // ou *a+*b qui est resolu resoud en (*a).operator+(*b);
la compilateur cherche la fonction A::f(B*);
Si il n'y a pas de fonction comme cela, il va chercher a transtype un B* en autre chose qu'il connait typiquement un A::F(void*).
Supposons que B* est bien defini, alors il va utiliser la fonction A::f(B*). Si cette fonction est virtuelle etque A est en fait de type X, la fonction appelle sera X::f(B*).
Comme tu peux le remarque le type deuxieme parametre n'est JAMAIS change. Si c'est un B* au debut, ca restera un B* a la fin.
Cependant, tu peux contourner ca (avec ce que les gens appelle un pattern de visiteur) en faisait que la fonction X::f(B*) appelle une fonction de B
par exemple:
something X::f(B* b)
{
return b->f(this);
}
Ici, this est deja type X* donc le compilateur va chercher une fonction qui match B::f(X*); si il y en a une, elle sera ensuite verifier pour polymorphisme et si B* est en fait de type Y, la fonction Y::f(X*) sera appelle et tu as bien tout tes types qui ont ete resolu.
Cela etant dit, je trouve ca chiant comme la pluie a utilise, en particulier par ce que tu as des tonnes de fonction "cretine" a ecrire.