Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Problème d'accès aux fonctions d'une hiérarchie de classes

2 réponses
Avatar
Michael
Bonjour à tous,

je me trouve face à un souci que je n'arrive pas à résoudre:

class fooBase
{
public:
fooBase();

virtual void AddTo();
virtual void RemoveFrom();

virtual void Set();
};

class fooBase2 : public fooBase
{
public:
fooBase2();

virtual void AddTo();
virtual void RemoveFrom();
};

class fooImpl : public fooBase
{
public:
fooImpl();

void Special();
};

void Bind(fooBase & f)
{
f.Set();
}

class toto
{
private:
fooImpl * f;
public:
toto();

void SetfooImpl(fooImpl * f_)
{
f = f_;
f->AddTo();
}
};

Mon problème est que je veux rendre les fonctions fooBase::AddTo() et
fooBase::RemoveFrom() accessibles seulement depuis la classe toto et la
fonction Bind. Je ne veux pas que l'utilisateur de ces classes y ait accès.

Une solution serait de les déclarer private et d'ajouter friend class toto;
dans la déclaration de fooBase, mais du coup ça ne marche plus avec la
fonction Bind();

D'autre part, j'ai également ce genre de classes:

class fooImpl2 : public fooImpl
{
private:
fooBase2 * f1;
public:
fooImpl2();

virtual void SetF1(fooBase2 * f1_)
{
if (f1 != NULL)
f1->RemoveFrom();
f1 = f1_;
}
};

Ce qui du coup m'obligerait en plus à ajouter friend class fooImpl2; dans
fooBase...

Comme j'ai un certain nombre de classes dérivées de ce genre, c'est AMHA
une solution qui ne convient pas...

Est-ce qu'il existe une solution générique à ce genre de soucis?

Merci d'avance

Michael

2 réponses

Avatar
Pierre Barbier de Reuille
Michael wrote:
Bonjour à tous,

je me trouve face à un souci que je n'arrive pas à résoudre:

class fooBase
{
public:
fooBase();

virtual void AddTo();
virtual void RemoveFrom();

virtual void Set();
};

class fooBase2 : public fooBase
{
public:
fooBase2();

virtual void AddTo();
virtual void RemoveFrom();
};

class fooImpl : public fooBase
{
public:
fooImpl();

void Special();
};

void Bind(fooBase & f)
{
f.Set();
}

class toto
{
private:
fooImpl * f;
public:
toto();

void SetfooImpl(fooImpl * f_)
{
f = f_;
f->AddTo();
}
};

Mon problème est que je veux rendre les fonctions fooBase::AddTo() et
fooBase::RemoveFrom() accessibles seulement depuis la classe toto et la
fonction Bind. Je ne veux pas que l'utilisateur de ces classes y ait accès.


Souvent ce genre de problème vient d'un design pas adapté !
Par exemple, pourquoi la fonction Bind n'est pas une méthode de fooBase
? Si tu veux vraiment que ce soit une fonction, alors tu peux toujours
faire une méthode publique qui s'occupe de la fonctionnalité et la
fonction se contente d'appeler la méthode ...


Une solution serait de les déclarer private et d'ajouter friend class toto;
dans la déclaration de fooBase, mais du coup ça ne marche plus avec la
fonction Bind();

D'autre part, j'ai également ce genre de classes:

class fooImpl2 : public fooImpl
{
private:
fooBase2 * f1;
public:
fooImpl2();

virtual void SetF1(fooBase2 * f1_)
{
if (f1 != NULL)
f1->RemoveFrom();
f1 = f1_;
}
};

Ce qui du coup m'obligerait en plus à ajouter friend class fooImpl2; dans
fooBase...

Comme j'ai un certain nombre de classes dérivées de ce genre, c'est AMHA
une solution qui ne convient pas...


Pour ton problème de classe dérivée, soit, comme suggéré plus haut, tu
peux imaginer une fonction de plus haut niveau dans fooBase qui soit
publique, soit tu peux définir une fonction protégée (protected) dans
fooImpl qui implémente ce que tu veux, et tu déclare simplement fooImpl
comme classe amie de fooBase.

Mais encore une fois, il est très rare qu'une déclaration de classe (ou
fonction) amie soit la bonne solution ... c'est souvent que tu as besoin
d'une méthode publique de plus haut niveau (par exemple, qui conserve
les invariants).

Pierre


Est-ce qu'il existe une solution générique à ce genre de soucis?

Merci d'avance

Michael


Avatar
Michael
Pour ton problŠme de classe d‚riv‚e, soit, comme sugg‚r‚ plus haut, tu
peux imaginer une fonction de plus haut niveau dans fooBase qui soit
publique, soit tu peux d‚finir une fonction prot‚g‚e (protected) dans
fooImpl qui impl‚mente ce que tu veux, et tu d‚clare simplement fooImpl
comme classe amie de fooBase.


Je ne vois pas vraiment ce que tu veux dire...

Si je définis une fonction de plus haut niveau dans fooBase (pour AddTo() par
exemple), elle sera toujours accessible à tout le monde; or, seule toto
devrait pouvoir y accéder...