Je me retrouve confront=E9 =E0 un petit probl=E8me de conception : J'ai
une classe "Waitable" dont h=E9rite plusieurs types "Mutex",
"Semaphore", "MaPrimitiveBloquanteAMoi", etc...
Waitable a une m=E9thode statique WaitMultiple. Au d=E9part, je pensais
=E9crire:
ReturnType Waitable::WaitMultiple(vector<Waitable*> objects, bool
WaitAll, unsigned timeout);
Le probl=E8me est qu'=E0 l'utilisation, j'ai le plus souvent un
vector<Mutex*> ou bien un vector<Semaphore*>, etc... Hors
vector<Derived*> n'est pas convertible en vector<Base*> : je comprends
bien le pourquoi de cette limitation, mais comment =E9crire
WaitMultiple?
La seule solution qui m'est venu =E0 l'esprit, c'est de passer un
tableau "=E0 la C" =E0 WaitMultiple (avec sa taille), et ca ne me plait
pas. Y'a-t-il d'autres alternatives?
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Aurélien REGAT-BARREL
Bonjour,
Tu peux créer WaitMultiple comme étant une fonction membre template qui accepte un vector de T, T étant considéré comme un Base*.
-- Aurélien REGAT-BARREL
wrote:
Bonjour,
Je me retrouve confronté à un petit problème de conception : J'ai une classe "Waitable" dont hérite plusieurs types "Mutex", "Semaphore", "MaPrimitiveBloquanteAMoi", etc...
Waitable a une méthode statique WaitMultiple. Au départ, je pensais écrire: ReturnType Waitable::WaitMultiple(vector<Waitable*> objects, bool WaitAll, unsigned timeout);
Le problème est qu'à l'utilisation, j'ai le plus souvent un vector<Mutex*> ou bien un vector<Semaphore*>, etc... Hors vector<Derived*> n'est pas convertible en vector<Base*> : je comprends bien le pourquoi de cette limitation, mais comment écrire WaitMultiple?
La seule solution qui m'est venu à l'esprit, c'est de passer un tableau "à la C" à WaitMultiple (avec sa taille), et ca ne me plait pas. Y'a-t-il d'autres alternatives?
Merci d'avance.
Arnaud
Bonjour,
Tu peux créer WaitMultiple comme étant une fonction membre template qui
accepte un vector de T, T étant considéré comme un Base*.
--
Aurélien REGAT-BARREL
adebaene@club-internet.fr wrote:
Bonjour,
Je me retrouve confronté à un petit problème de conception : J'ai
une classe "Waitable" dont hérite plusieurs types "Mutex",
"Semaphore", "MaPrimitiveBloquanteAMoi", etc...
Waitable a une méthode statique WaitMultiple. Au départ, je pensais
écrire:
ReturnType Waitable::WaitMultiple(vector<Waitable*> objects, bool
WaitAll, unsigned timeout);
Le problème est qu'à l'utilisation, j'ai le plus souvent un
vector<Mutex*> ou bien un vector<Semaphore*>, etc... Hors
vector<Derived*> n'est pas convertible en vector<Base*> : je comprends
bien le pourquoi de cette limitation, mais comment écrire
WaitMultiple?
La seule solution qui m'est venu à l'esprit, c'est de passer un
tableau "à la C" à WaitMultiple (avec sa taille), et ca ne me plait
pas. Y'a-t-il d'autres alternatives?
Tu peux créer WaitMultiple comme étant une fonction membre template qui accepte un vector de T, T étant considéré comme un Base*.
-- Aurélien REGAT-BARREL
wrote:
Bonjour,
Je me retrouve confronté à un petit problème de conception : J'ai une classe "Waitable" dont hérite plusieurs types "Mutex", "Semaphore", "MaPrimitiveBloquanteAMoi", etc...
Waitable a une méthode statique WaitMultiple. Au départ, je pensais écrire: ReturnType Waitable::WaitMultiple(vector<Waitable*> objects, bool WaitAll, unsigned timeout);
Le problème est qu'à l'utilisation, j'ai le plus souvent un vector<Mutex*> ou bien un vector<Semaphore*>, etc... Hors vector<Derived*> n'est pas convertible en vector<Base*> : je comprends bien le pourquoi de cette limitation, mais comment écrire WaitMultiple?
La seule solution qui m'est venu à l'esprit, c'est de passer un tableau "à la C" à WaitMultiple (avec sa taille), et ca ne me plait pas. Y'a-t-il d'autres alternatives?
Merci d'avance.
Arnaud
Christophe de VIENNE
Bonjour,
Je me retrouve confronté à un petit problème de conception : J'ai une classe "Waitable" dont hérite plusieurs types "Mutex", "Semaphore", "MaPrimitiveBloquanteAMoi", etc...
Waitable a une méthode statique WaitMultiple. Au départ, je pensais écrire: ReturnType Waitable::WaitMultiple(vector<Waitable*> objects, bool WaitAll, unsigned timeout);
Le problème est qu'à l'utilisation, j'ai le plus souvent un vector<Mutex*> ou bien un vector<Semaphore*>, etc... Hors vector<Derived*> n'est pas convertible en vector<Base*> : je comprends bien le pourquoi de cette limitation, mais comment écrire WaitMultiple?
Une possibilité est d'utiliser les templates :
! class Waitable { ! template<InputIterator> ! static ReturnType WaitMultiple(InputIterator first, InputIterator last, bool WaitAll, unsigned timeout); ! }
Comme ça tu peux donner en paramètre n'importe quel conteneur (ses iterateurs de début et de fin pour être exact) contenant des objets dérivant de Waitable.
A+
Christophe
-- Christophe de Vienne
Bonjour,
Je me retrouve confronté à un petit problème de conception : J'ai
une classe "Waitable" dont hérite plusieurs types "Mutex",
"Semaphore", "MaPrimitiveBloquanteAMoi", etc...
Waitable a une méthode statique WaitMultiple. Au départ, je pensais
écrire:
ReturnType Waitable::WaitMultiple(vector<Waitable*> objects, bool
WaitAll, unsigned timeout);
Le problème est qu'à l'utilisation, j'ai le plus souvent un
vector<Mutex*> ou bien un vector<Semaphore*>, etc... Hors
vector<Derived*> n'est pas convertible en vector<Base*> : je comprends
bien le pourquoi de cette limitation, mais comment écrire
WaitMultiple?
Une possibilité est d'utiliser les templates :
! class Waitable {
! template<InputIterator>
! static ReturnType WaitMultiple(InputIterator first,
InputIterator last, bool WaitAll, unsigned timeout);
! }
Comme ça tu peux donner en paramètre n'importe quel conteneur (ses
iterateurs de début et de fin pour être exact) contenant des objets
dérivant de Waitable.
Je me retrouve confronté à un petit problème de conception : J'ai une classe "Waitable" dont hérite plusieurs types "Mutex", "Semaphore", "MaPrimitiveBloquanteAMoi", etc...
Waitable a une méthode statique WaitMultiple. Au départ, je pensais écrire: ReturnType Waitable::WaitMultiple(vector<Waitable*> objects, bool WaitAll, unsigned timeout);
Le problème est qu'à l'utilisation, j'ai le plus souvent un vector<Mutex*> ou bien un vector<Semaphore*>, etc... Hors vector<Derived*> n'est pas convertible en vector<Base*> : je comprends bien le pourquoi de cette limitation, mais comment écrire WaitMultiple?
Une possibilité est d'utiliser les templates :
! class Waitable { ! template<InputIterator> ! static ReturnType WaitMultiple(InputIterator first, InputIterator last, bool WaitAll, unsigned timeout); ! }
Comme ça tu peux donner en paramètre n'importe quel conteneur (ses iterateurs de début et de fin pour être exact) contenant des objets dérivant de Waitable.
A+
Christophe
-- Christophe de Vienne
korchkidu
wrote:
Bonjour,
Le problème est qu'à l'utilisation, j'ai le plus souvent un vector<Mutex*> ou bien un vector<Semaphore*>, etc... Hors vector<Derived*> n'est pas convertible en vector<Base*> : je comprends bien le pourquoi de cette limitation, mais comment écrire WaitMultiple? Ben moi je comprends pas vraiment le pourquoi de cette limitation en fait...
Qq1 peut detailler SVP?
K.
adebaene@club-internet.fr wrote:
Bonjour,
Le problème est qu'à l'utilisation, j'ai le plus souvent un
vector<Mutex*> ou bien un vector<Semaphore*>, etc... Hors
vector<Derived*> n'est pas convertible en vector<Base*> : je comprends
bien le pourquoi de cette limitation, mais comment écrire
WaitMultiple?
Ben moi je comprends pas vraiment le pourquoi de cette limitation en fait...
Le problème est qu'à l'utilisation, j'ai le plus souvent un vector<Mutex*> ou bien un vector<Semaphore*>, etc... Hors vector<Derived*> n'est pas convertible en vector<Base*> : je comprends bien le pourquoi de cette limitation, mais comment écrire WaitMultiple? Ben moi je comprends pas vraiment le pourquoi de cette limitation en fait...
Qq1 peut detailler SVP?
K.
kanze
korchkidu wrote:
wrote:
Le problème est qu'à l'utilisation, j'ai le plus souvent un vector<Mutex*> ou bien un vector<Semaphore*>, etc... Hors vector<Derived*> n'est pas convertible en vector<Base*> : je comprends bien le pourquoi de cette limitation, mais comment écrire WaitMultiple?
Ben moi je comprends pas vraiment le pourquoi de cette limitation en fait... Qq1 peut detailler SVP?
Sans doute parce qu'on l'estimait inutile, étant donné le temps d'exécution qu'il exigerait. Une conversion implique la création d'un nouveau object.
Si tu le veux vraiment, et que tu as un object vector<Derived*>, tu peux bien faire:
Ça fait exactement ce que ferait le cast, s'il était légal.
-- 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
korchkidu wrote:
adebaene@club-internet.fr wrote:
Le problème est qu'à l'utilisation, j'ai le plus souvent un
vector<Mutex*> ou bien un vector<Semaphore*>, etc... Hors
vector<Derived*> n'est pas convertible en vector<Base*> : je
comprends bien le pourquoi de cette limitation, mais comment
écrire WaitMultiple?
Ben moi je comprends pas vraiment le pourquoi de cette
limitation en fait... Qq1 peut detailler SVP?
Sans doute parce qu'on l'estimait inutile, étant donné le temps
d'exécution qu'il exigerait. Une conversion implique la création
d'un nouveau object.
Si tu le veux vraiment, et que tu as un object vector<Derived*>,
tu peux bien faire:
Le problème est qu'à l'utilisation, j'ai le plus souvent un vector<Mutex*> ou bien un vector<Semaphore*>, etc... Hors vector<Derived*> n'est pas convertible en vector<Base*> : je comprends bien le pourquoi de cette limitation, mais comment écrire WaitMultiple?
Ben moi je comprends pas vraiment le pourquoi de cette limitation en fait... Qq1 peut detailler SVP?
Sans doute parce qu'on l'estimait inutile, étant donné le temps d'exécution qu'il exigerait. Une conversion implique la création d'un nouveau object.
Si tu le veux vraiment, et que tu as un object vector<Derived*>, tu peux bien faire:
Ça fait exactement ce que ferait le cast, s'il était légal.
-- 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
adebaene
korchkidu wrote:
wrote:
Bonjour,
Le problème est qu'à l'utilisation, j'ai le plus souvent un vector<Mutex*> ou bien un vector<Semaphore*>, etc... Hors vector<Derived*> n'est pas convertible en vector<Base*> : je comprends
bien le pourquoi de cette limitation, mais comment écrire WaitMultiple? Ben moi je comprends pas vraiment le pourquoi de cette limitation en
fait...
Qq1 peut detailler SVP?
Voilà ce qu'on pourrait faire si la conversion était autorisée :
vector<Derived*> t; t.push_back(new Derived); //ok : t ne contient que des Derived*
function(t); //oups! le contenu de t est hétérogène!!!
En fait, il faudrait permettre uniquement la conversion vector<Derived*> --> const vector<Base*>, mais je ne pense pas que le langage le permette.
Arnaud
korchkidu wrote:
adebaene@club-internet.fr wrote:
Bonjour,
Le problème est qu'à l'utilisation, j'ai le plus souvent un
vector<Mutex*> ou bien un vector<Semaphore*>, etc... Hors
vector<Derived*> n'est pas convertible en vector<Base*> : je
comprends
bien le pourquoi de cette limitation, mais comment écrire
WaitMultiple?
Ben moi je comprends pas vraiment le pourquoi de cette limitation en
fait...
Qq1 peut detailler SVP?
Voilà ce qu'on pourrait faire si la conversion était autorisée :
Le problème est qu'à l'utilisation, j'ai le plus souvent un vector<Mutex*> ou bien un vector<Semaphore*>, etc... Hors vector<Derived*> n'est pas convertible en vector<Base*> : je comprends
bien le pourquoi de cette limitation, mais comment écrire WaitMultiple? Ben moi je comprends pas vraiment le pourquoi de cette limitation en
fait...
Qq1 peut detailler SVP?
Voilà ce qu'on pourrait faire si la conversion était autorisée :
On Wed, 23 Feb 2005 10:04:34 -0500, "Michel Michaud" :
Comme quoi, on ne peut pas utiliser un pointeur sur une classe dérivée partout où l'on peut utiliser un pointeur sur la classe de base... :-)
C'est exact, et j'espère que personne n'a dit le contraire.
-- ;-)
Arnaud Debaene
Christophe de VIENNE wrote:
Une possibilité est d'utiliser les templates :
! class Waitable { ! template<InputIterator> ! static ReturnType WaitMultiple(InputIterator first, InputIterator last, bool WaitAll, unsigned timeout); ! }
Comme ça tu peux donner en paramètre n'importe quel conteneur (ses iterateurs de début et de fin pour être exact) contenant des objets dérivant de Waitable.
Merci à Christophe et Aurélien pour leurs idées. Je n'ai pas encore le réflexe"template" pour ce genre de problèmes :-)
Arnaud
Christophe de VIENNE wrote:
Une possibilité est d'utiliser les templates :
! class Waitable {
! template<InputIterator>
! static ReturnType WaitMultiple(InputIterator first,
InputIterator last, bool WaitAll, unsigned timeout);
! }
Comme ça tu peux donner en paramètre n'importe quel conteneur (ses
iterateurs de début et de fin pour être exact) contenant des objets
dérivant de Waitable.
Merci à Christophe et Aurélien pour leurs idées. Je n'ai pas encore le
réflexe"template" pour ce genre de problèmes :-)
! class Waitable { ! template<InputIterator> ! static ReturnType WaitMultiple(InputIterator first, InputIterator last, bool WaitAll, unsigned timeout); ! }
Comme ça tu peux donner en paramètre n'importe quel conteneur (ses iterateurs de début et de fin pour être exact) contenant des objets dérivant de Waitable.
Merci à Christophe et Aurélien pour leurs idées. Je n'ai pas encore le réflexe"template" pour ce genre de problèmes :-)
Arnaud
kanze
Michel Michaud wrote:
Dans le message , a
korchkidu wrote:
wrote:
vector<Derived*> n'est pas convertible en vector<Base*> : je Ben moi je comprends pas vraiment le pourquoi de cette
limitation en fait... Qq1 peut detailler SVP?
Voilà ce qu'on pourrait faire si la conversion était autorisée : [...]
En fait, pour la même raison,
void F(Base*&);
n'accepte pas non plus
Derivé* p; F(p);
Je ne vois pas le rapport. Dans ton exemple, il s'agit d'une conversion de référence, dont le résultat est un lvalue, qui doit permettre l'accès direct à l'objet initial. Dans le cas en question, il s'agit de convertir un objet de type vector<Derived*> en objet de type vector<Base*>. En principe, on pourrait très bien le supporter -- on peut en fait avoir exactement le même résultat déjà avec une syntaxe légèrement différente :
et son équivalent const. Seulement, j'imagine que très peu de gens aimeraient qu'une telle conversion soit implicite. Avec quelque chose comme boost::enable_if ou des contraints, on pourrait ajouter un constructeur :
template< typename C > std::vector<T>::vector( C const& other ) { // Contraint : C a des fonctions membre begin() et end() // initialiser avec other.begin() et other.end() ... }
Constructeur qu'on ferait explicit, évidemment.
Mais est-ce qu'on veut réelement de telles conversions, vue leur prix en temps d'exécution. Je ne suis pas exactement ce qu'on pourrait qualifier de maniaque de performance, mais il y a des limites même pour moi. (Encore qu'explicit...)
Comme quoi, on ne peut pas utiliser un pointeur sur une classe dérivée partout où l'on peut utiliser un pointeur sur la classe de base... :-)
Dit comme ça... Mais la règle, c'est qu'on peut se servir d'un objet de type dérivé partout où on peut se servir d'un objet de type base. C'est clair qu'il n'y a aucun rapport d'héritage entre les pointeurs mêmes, quand on les considère comme des objets.
-- 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
Michel Michaud wrote:
Dans le message
1109168610.374725.170390@g14g2000cwa.googlegroups.com,
adebaene@club-internet.fr <adebaene@club-internet.fr> a
korchkidu wrote:
adebaene@club-internet.fr wrote:
vector<Derived*> n'est pas convertible en vector<Base*> :
je
Ben moi je comprends pas vraiment le pourquoi de cette
limitation en fait... Qq1 peut detailler SVP?
Voilà ce qu'on pourrait faire si la conversion était
autorisée :
[...]
En fait, pour la même raison,
void F(Base*&);
n'accepte pas non plus
Derivé* p;
F(p);
Je ne vois pas le rapport. Dans ton exemple, il s'agit d'une
conversion de référence, dont le résultat est un lvalue, qui
doit permettre l'accès direct à l'objet initial. Dans le cas en
question, il s'agit de convertir un objet de type
vector<Derived*> en objet de type vector<Base*>. En principe, on
pourrait très bien le supporter -- on peut en fait avoir
exactement le même résultat déjà avec une syntaxe légèrement
différente :
et son équivalent const. Seulement, j'imagine que très peu de
gens aimeraient qu'une telle conversion soit implicite. Avec
quelque chose comme boost::enable_if ou des contraints, on
pourrait ajouter un constructeur :
template< typename C >
std::vector<T>::vector( C const& other )
{
// Contraint : C a des fonctions membre begin() et end()
// initialiser avec other.begin() et other.end() ...
}
Constructeur qu'on ferait explicit, évidemment.
Mais est-ce qu'on veut réelement de telles conversions, vue
leur prix en temps d'exécution. Je ne suis pas exactement ce
qu'on pourrait qualifier de maniaque de performance, mais il y a
des limites même pour moi. (Encore qu'explicit...)
Comme quoi, on ne peut pas utiliser un pointeur sur une classe
dérivée partout où l'on peut utiliser un pointeur sur la
classe de base... :-)
Dit comme ça... Mais la règle, c'est qu'on peut se servir d'un
objet de type dérivé partout où on peut se servir d'un objet de
type base. C'est clair qu'il n'y a aucun rapport d'héritage
entre les pointeurs mêmes, quand on les considère comme des
objets.
--
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
vector<Derived*> n'est pas convertible en vector<Base*> : je Ben moi je comprends pas vraiment le pourquoi de cette
limitation en fait... Qq1 peut detailler SVP?
Voilà ce qu'on pourrait faire si la conversion était autorisée : [...]
En fait, pour la même raison,
void F(Base*&);
n'accepte pas non plus
Derivé* p; F(p);
Je ne vois pas le rapport. Dans ton exemple, il s'agit d'une conversion de référence, dont le résultat est un lvalue, qui doit permettre l'accès direct à l'objet initial. Dans le cas en question, il s'agit de convertir un objet de type vector<Derived*> en objet de type vector<Base*>. En principe, on pourrait très bien le supporter -- on peut en fait avoir exactement le même résultat déjà avec une syntaxe légèrement différente :
et son équivalent const. Seulement, j'imagine que très peu de gens aimeraient qu'une telle conversion soit implicite. Avec quelque chose comme boost::enable_if ou des contraints, on pourrait ajouter un constructeur :
template< typename C > std::vector<T>::vector( C const& other ) { // Contraint : C a des fonctions membre begin() et end() // initialiser avec other.begin() et other.end() ... }
Constructeur qu'on ferait explicit, évidemment.
Mais est-ce qu'on veut réelement de telles conversions, vue leur prix en temps d'exécution. Je ne suis pas exactement ce qu'on pourrait qualifier de maniaque de performance, mais il y a des limites même pour moi. (Encore qu'explicit...)
Comme quoi, on ne peut pas utiliser un pointeur sur une classe dérivée partout où l'on peut utiliser un pointeur sur la classe de base... :-)
Dit comme ça... Mais la règle, c'est qu'on peut se servir d'un objet de type dérivé partout où on peut se servir d'un objet de type base. C'est clair qu'il n'y a aucun rapport d'héritage entre les pointeurs mêmes, quand on les considère comme des objets.
-- 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