C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Fonctions virtuelles ''globalement pures''

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French)
View previous topic :: View next topic  
Author Message
Fabien LE LEZ
Guest





PostPosted: Mon Jun 12, 2006 9:11 am    Post subject: Fonctions virtuelles ''globalement pures'' Reply with quote



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





PostPosted: Tue Jun 13, 2006 9:11 am    Post subject: Re: Fonctions virtuelles ''globalement pures'' Reply with quote



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





PostPosted: Wed Jun 14, 2006 9:11 am    Post subject: Re: Fonctions virtuelles ''globalement pures'' Reply with quote



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





PostPosted: Wed Jun 14, 2006 2:39 pm    Post subject: Re: Fonctions virtuelles ''globalement pures'' Reply with quote

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





PostPosted: Wed Jun 14, 2006 3:05 pm    Post subject: Re: Fonctions virtuelles ''globalement pures'' Reply with quote

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





PostPosted: Wed Jun 14, 2006 5:01 pm    Post subject: Re: Fonctions virtuelles ''globalement pures'' Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French) All times are GMT
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.