Question
Après avoir modifié la description de mon précédent message , je me suis assis et j'ai essayé de transmettre mes intention exacte.
J'ai une classe appelée P qui remplit un objectif distinct. J'ai également des PW qui remplissent des fonctions distinctes sur P. PW n'a pas de variables membres, mais uniquement des fonctions membres.
A partir de cette description, vous supposeriez que le code suivrait comme suit:
class P
{
public:
void a( );
};
class PW
{
public:
PW( const P& p ) : p( p ) { }
void b( );
P& p;
};
class C
{
public:
P GetP( ) const { return p; }
private:
P p;
};
// ...
PW& p = c.GetP( ); // valid
// ...
Cependant, cela soulève un problème. Je ne peux pas appeler les fonctions de P sans indirection partout.
// ...
p->p->a( )
// ...
Ce que je voudrais faire, c'est appeler p- > a () et le laisser déterminer automatiquement que je souhaite appeler la fonction membre de P.
Avoir également un membre de PW appelé a n'a pas vraiment d'échelle - que se passe-t-il si j'ajoute (ou supprime) une autre fonction à P - cela devra être ajouté (ou supprimé) à PW.
La solution
Vous pouvez essayer de remplacer l'opérateur * et l'opérateur- > pour rendre l'accès à la p intégrée. Quelque chose comme ça pourrait faire l'affaire:
class P
{
public:
void a( ) { std::cout << "a" << std::endl; }
};
class PW
{
public:
PW(P& p) : p(p) { }
void b( ) { std::cout << "b" << std::endl; }
P & operator*() { return p; }
P * operator->() { return &p; }
private:
P & p;
};
class C
{
public:
P & getP() { return p; }
private:
P p;
};
int main()
{
C c;
PW pw(c.getP());
(*pw).a();
pw->a();
pw.b();
return EXIT_SUCCESS;
}
Ce code est imprimé
a
a
b
Cependant, cette méthode peut dérouter l'utilisateur car la sémantique de l'opérateur * et de l'opérateur- > devient un peu foiré.
Autres conseils
Si vous faites de P une super-classe à PW, comme vous l'avez fait dans votre question précédente, vous pouvez appeler p- > a () et vous diriger vers la classe P. Il semble que vous ayez déjà envisagé et rejeté cette proposition. , à en juger par cette question. Si oui, voudriez-vous expliquer pourquoi cela ne fonctionnera pas pour vous?
Je pense que vous devez réfléchir au type de relation existant entre PW et P.
Est-ce une relation is-a? Les instances PW sont-elles des instances de P? Il serait alors logique que PW hérite de P.
Est-ce une relation has-a? Ensuite, vous devriez vous en tenir au confinement et supporter le désagrément syntaxique.
Incidemment, ce n'est généralement pas une bonne idée d'exposer une référence non const à une variable membre dans l'interface publique d'une classe.