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 

polymorphisme static

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





PostPosted: Sat Jun 12, 2004 5:11 pm    Post subject: polymorphisme static Reply with quote



salut

je cherche un moyen d'appeler à partir d'une classe de base (template)
un membre d'une classe dérivé,

note 1/ get_wave ne peu pas etre virtual (performance, vtable...)
note 2/ get_wave ne peu pas etre static (utilisation membres freq & ampl)


pseudo code


template <typename T>
struct osc
{
protected:
float frequency;
float amplitude;

public:
float get_wave(); // polymorphisme static ???? comment faire
inline void work(float* buf, unsigned long len)
{
// foreach samples
osc<T>::get_wave();

}
};



struct sine : public osc<sine>
{
inline float get_wave()
{
// compute
}
};



//
sine osc;
osc.work(foo, 512); // erreur de link (get_wave de osc)


si quelqu'un a une idée ?

foo

Back to top
Franck Branjonneau
Guest





PostPosted: Sat Jun 12, 2004 7:45 pm    Post subject: Re: polymorphisme static Reply with quote



foo <foo (AT) spam (DOT) net> écrivait:

Quote:
salut

je cherche un moyen d'appeler à partir d'une classe de base (template)
un membre d'une classe dérivé,

note 1/ get_wave ne peu pas etre virtual (performance, vtable...)
note 2/ get_wave ne peu pas etre static (utilisation membres freq & ampl)

La note 2 n'a pas de sens : rends explicite this.

Quote:
pseudo code


template <typename T
struct osc
{
protected:
float frequency;
float amplitude;

public:
float get_wave(); // polymorphisme static ???? comment faire

{ return T::get_wave(); }
--
Franck Branjonneau
Back to top
Vincent Richard
Guest





PostPosted: Sun Jun 13, 2004 8:28 am    Post subject: Re: polymorphisme static Reply with quote



Le Saturday 12 June 2004 07:11 pm, foo a écrit :

Quote:
je cherche un moyen d'appeler à partir d'une classe de base (template)
un membre d'une classe dérivé,

note 1/ get_wave ne peu pas etre virtual (performance, vtable...)

Franchement, tu as mesuré les performances ? J'avais déjà posé une question
similaire ici, il y a quelques temps, et finalement j'avais fini par faire
des tests.

J'ai été extrêmement étonné des résultats...

Quote:
 inline void work(float* buf, unsigned long len)
 {
     // foreach samples
     osc<T>::get_wave();

Si j'ai bien compris ce que tu veux faire, tu peux écrire :

dynamic_cast <osc (this)->get_wave();

(et enlever la déclaration de get_wave() dans osc.)

Je n'ai pas essayé, donc je ne sais même pas si ça compile et encore moins
si c'est légal. Par contre, je doute que ça soit plus performant que la
fonction virtuelle...

Et dans le cas où get_wave() est virtuelle pure (virtual ...() = 0), je
suppose que le compilo doit se permettre un tas d'optimisations...

Vincent

--
vmime, une bibliothèque C++ sous licence GPL pour parser et générer
des messages au format MIME : http://www.sourceforge.net/projects/vmime/

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Mon Jun 14, 2004 8:18 am    Post subject: Re: polymorphisme static Reply with quote

Vincent Richard <chere-loque.MARRE-DE-LA-PUB (AT) wanadoo (DOT) fr.invalid> wrote
in message news:<40cc0f57$0$13928$636a15ce (AT) news (DOT) free.fr>...
Quote:
Le Saturday 12 June 2004 07:11 pm, foo a écrit :

je cherche un moyen d'appeler à partir d'une classe de base
(template) un membre d'une classe dérivé,

note 1/ get_wave ne peu pas etre virtual (performance, vtable...)

Franchement, tu as mesuré les performances ? J'avais déjà posé une
question similaire ici, il y a quelques temps, et finalement j'avais
fini par faire des tests.

J'ai été extrêmement étonné des résultats...

inline void work(float* buf, unsigned long len)
{
// foreach samples
osc<T>::get_wave();

Si j'ai bien compris ce que tu veux faire, tu peux écrire :

dynamic_cast <osc (this)->get_wave();

(et enlever la déclaration de get_wave() dans osc.)

Je n'ai pas essayé, donc je ne sais même pas si ça compile et encore
moins si c'est légal. Par contre, je doute que ça soit plus performant
que la fonction virtuelle...

Un dynamic_cast est prèsque sûrement moins performant que l'appel d'une
fonction virtuelle.

Il n'était pas tout à fait claire dans sa présentation. *Si* le type est
connu au moment de la compilation, comme c'était le cas dans son
exemple, il n'y a aucune différence dans les performances des fonctions
virtuelles et les performances des non-virtuelles. Si le type n'est pas
connu, et varie lors de l'execution, en général, les fonctions
virtuelles, c'est la solution la plus performante ; les alternatifs
(switch, etc.) sont en général encore moins rapide.

Dans la passée, je me suis servi d'un truc que j'ai appris de Barton et
Nackman, pour pouvoir se passer de la virtualité quand je connaissais le
type, tout en l'ayant quand je ne le connaissais pas. En gros, ça se
présentait un peu comme :

class Oscillation
{
public:
float getWave() const
{
return doGetWave() ;
}

private:
virtual float doGetWave() const = 0 ;
} ;

class Sine : public Oscillation
{
public:
float getWave() const ; // Avec la vraie implémentation

private:
virtual float doGetWave() const
{
return getWave() ;
}
} ;

Si j'appelle getWave à travers une référence à Oscillation, j'ai bien un
appel virtuel. Si je l'appelle à travers une référence à Sine, en
revanche, j'ai un appel direct à la fonction, sans virtualité.

Tel qu'il l'a présenté, je ne sais pas si ça lui conviendrait. J'avais
l'impression qu'il n'utilise pas le polymorphisme ; qu'il connaît
toujours le type en question. Dans ce cas-là, d'abord, on se pose la
question : pourquoi l'héritage. Si c'est la facturation du code commun
aux tous les oscillations, c'est effectivement une solution, mais je
verrais aujourd'hui plutôt une solution avec des traits, du genre :

template< typename Traits >
class Oscillation
{
// ...
void work( std::vector< float > const& buffer )
{
// ...
Traits::getWave( this ) ;
// ...
}
} ;

typedef Oscillation< SineTraits > Sine ;

Sinon, sa solution est aussi jouable, avec des static_cast dans la
classe de base :

static_cast< T >( this )->getWave() ;

Dans ce cas-ci, j'essaierais d'implémenter une vérification de concept
pour asserter que T dérive de Oscillation< T >. Quelque chose du genre :

Oscillation< T >* p = static_cast< T* >( 0 ) ;

dans le constructeur, par exemple.

--
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
Alexandre
Guest





PostPosted: Mon Jun 14, 2004 4:31 pm    Post subject: Re: polymorphisme static Reply with quote

Quote:
dynamic_cast <osc (this)->get_wave();

pour dynamic_cast ne faut-il pas que la classe ait une méthode virtuelle ?

Quote:
Un dynamic_cast est prèsque sûrement moins performant que l'appel d'une
fonction virtuelle.

surement. De plus, je ne suis même pas sur qu'il ait un sens sans méthodes
virtuelles dans la classe...

Quote:

Il n'était pas tout à fait claire dans sa présentation. *Si* le type est
connu au moment de la compilation, comme c'était le cas dans son
exemple, il n'y a aucune différence dans les performances des fonctions
virtuelles et les performances des non-virtuelles. Si le type n'est pas
connu, et varie lors de l'execution, en général, les fonctions
virtuelles, c'est la solution la plus performante ; les alternatifs
(switch, etc.) sont en général encore moins rapide.

Dans la passée, je me suis servi d'un truc que j'ai appris de Barton et
Nackman, pour pouvoir se passer de la virtualité quand je connaissais le
type, tout en l'ayant quand je ne le connaissais pas. En gros, ça se
présentait un peu comme :

class Oscillation
{
public:
float getWave() const
{
return doGetWave() ;
}

private:
virtual float doGetWave() const = 0 ;
} ;

class Sine : public Oscillation
{
public:
float getWave() const ; // Avec la vraie
implémentation

private:
virtual float doGetWave() const
{
return getWave() ;
}
} ;

Si j'appelle getWave à travers une référence à Oscillation, j'ai bien un
appel virtuel. Si je l'appelle à travers une référence à Sine, en
revanche, j'ai un appel direct à la fonction, sans virtualité.

Tel qu'il l'a présenté, je ne sais pas si ça lui conviendrait. J'avais
l'impression qu'il n'utilise pas le polymorphisme ; qu'il connaît
toujours le type en question. Dans ce cas-là, d'abord, on se pose la
question : pourquoi l'héritage. Si c'est la facturation du code commun
aux tous les oscillations, c'est effectivement une solution, mais je
verrais aujourd'hui plutôt une solution avec des traits, du genre :

template< typename Traits
class Oscillation
{
// ...
void work( std::vector< float > const& buffer )
{
// ...
Traits::getWave( this ) ;
// ...
}
} ;

typedef Oscillation< SineTraits > Sine ;

Sinon, sa solution est aussi jouable, avec des static_cast dans la
classe de base :

static_cast< T >( this )->getWave() ;

Dans ce cas-ci, j'essaierais d'implémenter une vérification de concept
pour asserter que T dérive de Oscillation< T >. Quelque chose du genre :

Oscillation< T >* p = static_cast< T* >( 0 ) ;

dans le constructeur, par exemple.

--
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@gabi-soft.fr
Guest





PostPosted: Tue Jun 15, 2004 8:01 am    Post subject: Re: polymorphisme static Reply with quote

"Alexandre" <alex.g (AT) netcourrier (DOT) com> wrote

Quote:
dynamic_cast <osc (this)->get_wave();

pour dynamic_cast ne faut-il pas que la classe ait une méthode
virtuelle ?

Tout à fait.

Le problème, c'est que tu as décris une partie d'une solution, mais non
le problème. Alors, on essaie de déviner. Ton code se basait sur un
héritage public ; neuf fois sur dix, l'héritage public sert à
l'implémentation du polymorphisme dynamique, à la OO. Ce qui suppose
aussi des fonctions virtuelles.

Si le but, c'est simplement de fournir une implémentation (ou une partie
d'implémentation) commune à la classe dérivée, sans que l'utilisateur
soit amené à « connaître » la classe de base, on préfère en général
l'héritage privé. Quand on ne peut pas se passer de l'héritage
complètement, au moyen de la délégation ou une classe de traits.

--
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
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.