 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Fabien LE LEZ Guest
|
Posted: Mon Jun 12, 2006 9:11 am Post subject: Fonctions virtuelles ''globalement pures'' |
|
|
Bonjour,
Soit la classe :
class C
{
public:
virtual ~C(){}
enum Couleur { ROUGE, VERT };
virtual void f (Couleur couleur)
{
switch (couleur)
{
case ROUGE: f_Rouge(); break;
case VERT: f_Vert(); break;
};
}
virtual void f_Rouge() { f (ROUGE); }
virtual void f_Vert() { f (VERT); }
};
Les fonctions de cette classe sont "globalement virtuelles pures",
i.e. pour que ça marche, une classe dérivée doit redéfinir soit f(),
soit f_Rouge() et f_Vert().
Y a-t-il un moyen de tester cela à la compilation ?
Merci d'avance... |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Tue Jun 13, 2006 9:11 am Post subject: Re: Fonctions virtuelles ''globalement pures'' |
|
|
Fabien LE LEZ wrote:
| Quote: | Soit la classe :
class C
{
public:
virtual ~C(){}
enum Couleur { ROUGE, VERT };
virtual void f (Couleur couleur)
{
switch (couleur)
{
case ROUGE: f_Rouge(); break;
case VERT: f_Vert(); break;
};
}
virtual void f_Rouge() { f (ROUGE); }
virtual void f_Vert() { f (VERT); }
};
Les fonctions de cette classe sont "globalement virtuelles
pures", i.e. pour que ça marche, une classe dérivée doit
redéfinir soit f(), soit f_Rouge() et f_Vert().
Y a-t-il un moyen de tester cela à la compilation ?
|
Est-ce que quelque chose comme le suivant ne ferait-il pas
l'affaire :
template< bool overridesF > class Intermediate ;
class Base
{
public:
virtual ~Base() {}
enum Color { red, green } ;
virtual void f( Color color )
{
switch ( color ) {
case red :
fRed() ;
break ;
case green :
fGreen() ;
break ;
}
}
virtual void fRed() { f( red ) ; }
virtual void fGreen() { f( green ) ; }
private:
template< bool overridesF > friend class Intermediate ;
Base() {}
Base( Base const& ) ; // ou {}, si on veut supporter
// la copie.
} ;
template<>
class Intermediate< true > : public Base
{
public:
virtual void f( Color ) = 0 ;
} ;
template<>
class Intermediate< false > : public Base
{
public:
virtual void fRed() = 0 ;
virtual void fGreen() = 0 ;
} ;
Évidemment, ici, il faut que l'utilisateur dérive d'une des
instantiations de Intermediate : true s'il veut supplanter f,
false pour ne pas supplanter f, mais plutôt les autres
fonctions.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Wed Jun 14, 2006 9:11 am Post subject: Re: Fonctions virtuelles ''globalement pures'' |
|
|
Fabien LE LEZ wrote:
| Quote: | On 13 Jun 2006 00:51:49 -0700, "kanze" <kanze@gabi-soft.fr>:
template
class Intermediate< true > : public Base
Y a-t-il une réelle utilité aux templates ici ?
|
Tirer l'attention sur le parellelisme des deux classes, et
simplifier la documentation (une seule classe à documenter, non
deux).
| Quote: | Je verrais plutôt un
class Intermediate_2_fonctions ;
class Intermediate_1_fonction ;
// Note : ces noms sont assez nuls, il faudra trouver mieux
|
L'avantage du template, c'est effectivement qu'il n'y a qu'un
seul nom à trouver:-).
[...]
| Quote: | En fait, je préfère la solution de Marc
news:e6jcj9$2tp$1 (AT) talisker (DOT) lacave.net> : mettre le code dans
les classes "intermédiaires".
|
Moi aussi. Je n'y avais pas pensé ; je me suis laissé trop
conditionné par la formulation de ta question.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
| Back to top |
|
 |
Franck Branjonneau Guest
|
Posted: Wed Jun 14, 2006 2:39 pm Post subject: Re: Fonctions virtuelles ''globalement pures'' |
|
|
Fabien LE LEZ <gramster (AT) gramster (DOT) com> écrivait:
| Quote: | On 13 Jun 2006 00:51:49 -0700, "kanze" <kanze@gabi-soft.fr>:
template
class Intermediate< true > : public Base
Y a-t-il une réelle utilité aux templates ici ?
|
Peut-être...
struct Base { // abstraite
enum Couleur { ROUGE, VERT };
virtual void f(Couleur couleur)= 0;
virtual void f_Rouge()= 0;
virtual void f_Vert()= 0;
virtual ~Base()= 0;
};
template< typename _Derived >
struct Basic: virtual Base {
// Ta classe C originale ; elle implémente la logique de f,
// f_Rouge et f_Vert.
virtual void f (Couleur couleur)
{
switch (couleur)
{
case ROUGE: f_Rouge(); break;
case VERT: f_Vert(); break;
};
}
virtual void f_Rouge() { f (ROUGE); }
virtual void f_Vert() { f (VERT); }
};
Deux cas d'usage
struct A: virtual Base, private Basic< A > {
// Je supplante f
virtual void f(Couleur couleur) {
std::cout << "A::f\n";
}
};
struct B: virtual Base, private Basic< B > {
// Je supplante f_Rouge et f_Vert
virtual void f_Rouge() {
std::cout << "B::f_Rouge\n";
}
virtual void f_Vert() {
std::cout << "B::f_Vert\n";
}
};
Application
int
main() {
{
Base * base(new A());
base->f(Base::ROUGE);
base->f(Base::VERT);
base->f_Rouge();
base->f_Vert();
}
{
Base * base(new B());
base->f(Base::ROUGE);
base->f(Base::VERT);
base->f_Rouge();
base->f_Vert();
}
}
enum Color =
virtual
| Quote: |
Je verrais plutôt un
class Intermediate_2_fonctions ;
class Intermediate_1_fonction ;
// Note : ces noms sont assez nuls, il faudra trouver mieux
class Base
{
public:
[...]
private:
friend class Intermediate_2_fonctions ;
friend class Intermediate_1_fonction ;
[...]
} ;
class Intermediate_1_fonction : public Base
{
public:
virtual void f( Color ) = 0 ;
} ;
class Intermediate_2_fonctions: public Base
{
public:
virtual void fRed() = 0 ;
virtual void fGreen() = 0 ;
} ;
En fait, je préfère la solution de Marc
news:e6jcj9$2tp$1 (AT) talisker (DOT) lacave.net> : mettre le code dans les
classes "intermédiaires".
|
--
Boujou t'chu tè.
Franck Branjonneau |
|
| Back to top |
|
 |
Franck Branjonneau Guest
|
Posted: Wed Jun 14, 2006 3:05 pm Post subject: Re: Fonctions virtuelles ''globalement pures'' |
|
|
Fabien LE LEZ <gramster (AT) gramster (DOT) com> écrivait:
| Quote: | On 13 Jun 2006 00:51:49 -0700, "kanze" <kanze@gabi-soft.fr>:
template
class Intermediate< true > : public Base
Y a-t-il une réelle utilité aux templates ici ?
|
Peut-être...
struct Base { // abstraite
enum Couleur { ROUGE, VERT };
virtual void f(Couleur couleur)= 0;
virtual void f_Rouge()= 0;
virtual void f_Vert()= 0;
virtual ~Base()= 0;
};
template< typename _Derived >
struct Basic: virtual Base {
// Ta classe C originale ; elle implémente la logique de f,
// f_Rouge et f_Vert.
virtual void f (Couleur couleur)
{
switch (couleur)
{
case ROUGE: f_Rouge(); break;
case VERT: f_Vert(); break;
};
}
virtual void f_Rouge() { f (ROUGE); }
virtual void f_Vert() { f (VERT); }
};
Deux cas d'usage
struct A: virtual Base, private Basic< A > {
// Je supplante f
virtual void f(Couleur couleur) {
std::cout << "A::f\n";
}
};
struct B: virtual Base, private Basic< B > {
// Je supplante f_Rouge et f_Vert
virtual void f_Rouge() {
std::cout << "B::f_Rouge\n";
}
virtual void f_Vert() {
std::cout << "B::f_Vert\n";
}
};
Application
int
main() {
{
Base * base(new A());
base->f(Base::ROUGE);
base->f(Base::VERT);
base->f_Rouge();
base->f_Vert();
}
{
Base * base(new B());
base->f(Base::ROUGE);
base->f(Base::VERT);
base->f_Rouge();
base->f_Vert();
}
}
Je supersede, j'ai oublié de couper les citations inutiles :-(
--
Franck Branjonneau |
|
| Back to top |
|
 |
Fabien LE LEZ Guest
|
Posted: Wed Jun 14, 2006 5:01 pm Post subject: Re: Fonctions virtuelles ''globalement pures'' |
|
|
On Wed, 14 Jun 2006 12:05:53 +0200, Franck Branjonneau
<fasbjx (AT) free (DOT) fr>:
| Quote: |
Deux cas d'usage
struct A: virtual Base, private Basic< A > {
|
Ouais mais bon, ça ne force pas A à implémenter ce qu'il faut :
class A: public Basic<void*>
{
};
Et zou, A::f_Rouge() fait une jolie boucle infinie. Avec A qui hérite
de Base bien sûr. |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|