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 

Un petit problème de fonction virtuelle
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French)
View previous topic :: View next topic  
Author Message
Marc G
Guest





PostPosted: Thu Oct 26, 2006 3:39 am    Post subject: Un petit problème de fonction virtuelle Reply with quote



j'ai le code suivant :

class BaseProperty {
public :
virtual BaseProperty* type(void) { return this;}
int value(void) { return -1;}
};

// représente une propriété d'un certain type
template <typename U>
class Property : public BaseProperty {
public :
Property(U* u) : _u(u) {}
virtual Property* type(void) { return this;}
U value(void) { return *_u; }
U* _u;
};

Mon problème :
j'ai lu qu'on pouvait changer le type de retour d'une fonction virtuelle
comme je le fais pour la fonction type
(et j'ai déjà utilisé avec succès cette faculté dans d'autres programmes)

si j'écris :
int y=50;
Property<int> x(&y);
BaseProperty *xx=&x;
alors
xx->type()->value() vaut -1 et pas 50
pourquoi ?
normalement, type() retourne un pointeur Property<int>* et l'appel de
value() devrait valoir 50
le pb, c'est mon compilo ou moi Sad ?
en plus, si je regarde typeid(xx->type()).name(), j'ai BaseProperty * comme
réponse
mais si je définit la fonction type() pour qu'elle retourne des références,
typeid(xx->type()).name() vaut Property
C'est à n'y rien comprendre...
Merci de vos lumières.
Marc
Back to top
Pierre Barbier de Reuille
Guest





PostPosted: Thu Oct 26, 2006 7:48 am    Post subject: Re: Un petit problème de fonction virtuelle Reply with quote



Marc G wrote:
Quote:
j'ai le code suivant :

class BaseProperty {
public :
virtual BaseProperty* type(void) { return this;}
int value(void) { return -1;}
};

// représente une propriété d'un certain type
template <typename U
class Property : public BaseProperty {
public :
Property(U* u) : _u(u) {}
virtual Property* type(void) { return this;}
U value(void) { return *_u; }
U* _u;
};

Mon problème :
j'ai lu qu'on pouvait changer le type de retour d'une fonction virtuelle
comme je le fais pour la fonction type
(et j'ai déjà utilisé avec succès cette faculté dans d'autres programmes)

Je ne sais pas où tu as pu utiliser cette "possibilité" mais elle
n'est certainement normalisée !! Elle est même innimplémentable ...

En effet, disons que tu as ce code :

struct A
{
virtual ~A() {}
virtual int f() { return 0; }
};

struct B : public A
{
virtual B& f() { return *this; }
};

int main()
{
B b;
A &a = b;
int c = a.f();
B& d = b.f();
}

Disons que si B::f est bien la version surchargée de A::f, comment c
et d comparent ? Ils devraient être identiques, mais en même temps B&
c'est pas convertible en int :-/

Par contre, le code est tout à fait valide et B::f cache A::f ...

Pierre

Quote:

si j'écris :
int y=50;
Property<int> x(&y);
BaseProperty *xx=&x;
alors
xx->type()->value() vaut -1 et pas 50
pourquoi ?
normalement, type() retourne un pointeur Property<int>* et l'appel de
value() devrait valoir 50
le pb, c'est mon compilo ou moi Sad ?
en plus, si je regarde typeid(xx->type()).name(), j'ai BaseProperty * comme
réponse
mais si je définit la fonction type() pour qu'elle retourne des références,
typeid(xx->type()).name() vaut Property
C'est à n'y rien comprendre...
Merci de vos lumières.
Marc
Back to top
Jean-Marc Bourguet
Guest





PostPosted: Thu Oct 26, 2006 9:11 am    Post subject: Re: Un petit probleme de fonction virtuelle Reply with quote



"Pierre Barbier de Reuille" <pierre.barbierdereuille (AT) gmail (DOT) com> writes:

Quote:
Marc G wrote:
j'ai le code suivant :

class BaseProperty {
public :
virtual BaseProperty* type(void) { return this;}
int value(void) { return -1;}
};

// représente une propriété d'un certain type
template <typename U
class Property : public BaseProperty {
public :
Property(U* u) : _u(u) {}
virtual Property* type(void) { return this;}
U value(void) { return *_u; }
U* _u;
};

Mon problème :
j'ai lu qu'on pouvait changer le type de retour d'une fonction virtuelle
comme je le fais pour la fonction type
(et j'ai déjà utilisé avec succès cette faculté dans d'autres programmes)

Je ne sais pas où tu as pu utiliser cette "possibilité" mais elle
n'est certainement normalisée !! Elle est même innimplémentable ...

Le retour covariant est normalisé et implémentable. Mais il fait moins que
ce que pense Pierre.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Back to top
Guest






PostPosted: Thu Oct 26, 2006 9:11 am    Post subject: Re: Un petit problème de fonction virtuelle Reply with quote

dieu.tout.puiss...@gmail.com wrote:
Quote:
Marc G wrote:
j'ai le code suivant :

class BaseProperty {
public :
virtual BaseProperty* type(void) { return this;}
int value(void) { return -1;}
};

// représente une propriété d'un certain type
template <typename U
class Property : public BaseProperty {
public :
Property(U* u) : _u(u) {}
virtual Property* type(void) { return this;}
U value(void) { return *_u; }
U* _u;
};

Mon problème :
j'ai lu qu'on pouvait changer le type de retour d'une fonction virtuelle
comme je le fais pour la fonction type
(et j'ai déjà utilisé avec succès cette faculté dans d'autres programmes)

Oui, car les types de retour de "type()" ont une relation d'héritage
publique. Property* est >>dérivée<< de BaseProperty*. C'est
uniquement dans ces cas-là que les types de retour (uniquement
pointeurs ou références) peuvent différer. Cela se nomme la
covariance des types de retour.


si j'écris :
int y=50;
Property<int> x(&y);
BaseProperty *xx=&x;
alors
xx->type()->value() vaut -1 et pas 50
pourquoi ?
normalement, type() retourne un pointeur Property<int>* et l'appel de
value() devrait valoir 50
le pb, c'est mon compilo ou moi Sad ?
en plus, si je regarde typeid(xx->type()).name(), j'ai BaseProperty * comme
réponse

Il faut se mettre à la place du compilateur.
Le type statique de *xx est BaseProperty. Le fait que son type
dynamique soit Property change simplement les pointeurs des fonctions
virtuelles. Mais *xx est un BaseProperty, donc tout le typage défini
dans la classe BaseProperty (y compris le type de retour de ces
fonctions virtuelles) sera celui de xx.
Le type dynamique(et statique) de xx->type() sera donc BaseProperty *,
car xx->type() n'est qu'un pointeur. Tu l'obtiens en utilisant typeid :

typeid(xx->type().name() //BaseProperty *

Par contre, le type dynamique de l'objet pointé par xx->type() est
Property :
typeid(*xx->type().name() //Property

Donc si tu veux obtenir 50 et pas -1, il te suffit simplement de
déclarer "value()" virtual.

J'ai oublié de préciser que, dans ton code, tu peux déclarer

"value()" en virtual car x est un Property<int>, donc "value()" aura le
même type de retour dans Property et BaseProperty. Si tu utilises un
Property<double> par exemple, tu ne pourras plus déclarer "value()" en
fonction virtuelle.
Back to top
Guest






PostPosted: Thu Oct 26, 2006 9:11 am    Post subject: Re: Un petit problème de fonction virtuelle Reply with quote

Marc G wrote:
Quote:
j'ai le code suivant :

class BaseProperty {
public :
virtual BaseProperty* type(void) { return this;}
int value(void) { return -1;}
};

// représente une propriété d'un certain type
template <typename U
class Property : public BaseProperty {
public :
Property(U* u) : _u(u) {}
virtual Property* type(void) { return this;}
U value(void) { return *_u; }
U* _u;
};

Mon problème :
j'ai lu qu'on pouvait changer le type de retour d'une fonction virtuelle
comme je le fais pour la fonction type
(et j'ai déjà utilisé avec succès cette faculté dans d'autres programmes)

Oui, car les types de retour de "type()" ont une relation d'héritage
publique. Property* est >>dérivée<< de BaseProperty*. C'est
uniquement dans ces cas-là que les types de retour (uniquement
pointeurs ou références) peuvent différer. Cela se nomme la
covariance des types de retour.

Quote:

si j'écris :
int y=50;
Property<int> x(&y);
BaseProperty *xx=&x;
alors
xx->type()->value() vaut -1 et pas 50
pourquoi ?
normalement, type() retourne un pointeur Property<int>* et l'appel de
value() devrait valoir 50
le pb, c'est mon compilo ou moi Sad ?
en plus, si je regarde typeid(xx->type()).name(), j'ai BaseProperty * comme
réponse

Il faut se mettre à la place du compilateur.
Le type statique de *xx est BaseProperty. Le fait que son type
dynamique soit Property change simplement les pointeurs des fonctions
virtuelles. Mais *xx est un BaseProperty, donc tout le typage défini
dans la classe BaseProperty (y compris le type de retour de ces
fonctions virtuelles) sera celui de xx.
Le type dynamique(et statique) de xx->type() sera donc BaseProperty *,
car xx->type() n'est qu'un pointeur. Tu l'obtiens en utilisant typeid :

typeid(xx->type().name() //BaseProperty *

Par contre, le type dynamique de l'objet pointé par xx->type() est
Property :
typeid(*xx->type().name() //Property

Donc si tu veux obtenir 50 et pas -1, il te suffit simplement de
déclarer "value()" virtual.

Quote:
mais si je définit la fonction type() pour qu'elle retourne des références,
typeid(xx->type()).name() vaut Property

Dans ce cas-là, xx->type() renvoie directement l'objet et non un
pointeur. Le type dynamique de cet objet est donc Property :
typeid(xx->type()).name() // Property

Par contre, si tu récupéres le type de l'adresse d'un objet
xx->type() (ceci étant + ou - une manière de récupérer le type
statique de xx->type()), tu obtiens BaseProperty * :
typeid(&xx->type()).name() // BaseProperty *

C'est bien le type statique de xx->type() puisque BaseProperty& est le
type de retour de "type()" dans la classe BaseProperty, dont xx est un
pointeur.


En espérant que mes propos soient clairs.
Back to top
Jean-Marc Bourguet
Guest





PostPosted: Thu Oct 26, 2006 9:11 am    Post subject: Re: Un petit probleme de fonction virtuelle Reply with quote

"Marc G" <mgueguen (AT) metrica (DOT) fr> writes:

Quote:
j'ai le code suivant :

class BaseProperty {
public :
virtual BaseProperty* type(void) { return this;}
int value(void) { return -1;}
};

// représente une propriété d'un certain type
template <typename U
class Property : public BaseProperty {
public :
Property(U* u) : _u(u) {}
virtual Property* type(void) { return this;}
U value(void) { return *_u; }
U* _u;
};

Mon problème :
j'ai lu qu'on pouvait changer le type de retour d'une fonction virtuelle
comme je le fais pour la fonction type
(et j'ai déjà utilisé avec succès cette faculté dans d'autres programmes)
si j'écris :
int y=50;
Property<int> x(&y);
BaseProperty *xx=&x;
alors
xx->type()->value() vaut -1 et pas 50
pourquoi ?

Le retour covariant n'est qu'un moyen d'écrire

class BaseProperty {
public:
BaseProperty* type() { return type_(); }
protected:
virtual BaseProperty* type_() { return this; }
};

template <typename U>
class Property: public BaseProperty {
public:
Property* type() { return static_cast<Property*>(type_()); }
protected:
BaseProperty* type_() { return this; }
};

Et ne change rien à la vision statique du code.

Quote:
normalement, type() retourne un pointeur Property<int>* et l'appel de
value() devrait valoir 50
le pb, c'est mon compilo ou moi Sad ?
en plus, si je regarde typeid(xx->type()).name(), j'ai BaseProperty * comme
réponse

Normal, c'est bien le type du pointeur. Essaye
typeid(*xx->type()).name()
pour avoir le type pointé.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Back to top
Marc G
Guest





PostPosted: Thu Oct 26, 2006 9:11 am    Post subject: Re: Un petit problème de fonction virtuelle Reply with quote

je vais étudier ta solution plus en détail et l'implémenter dans mon cas
précis.
Si ça marche, tu me sauve la vie...
pour t'expliquer mon problème en général, je développe un interpréteur, avec
des objets et donc des propriétés associées à ces objets
exemple au hasard :
UnObjetInt x=5;
x.value; // retourne 5
x.name; // propriété valide, retourne un std::string
x.nimportequoi; // erreur , la propriété n'existe pas
et pour chaque propriété publiable, je cherche à définir des objets
"propriétés" qui représente des références vers les objets "modifiables"
voilà mon problème de façon simplifiée...
Marc
Back to top
Jean-Marc Bourguet
Guest





PostPosted: Thu Oct 26, 2006 9:11 am    Post subject: Re: Un petit probleme de fonction virtuelle Reply with quote

"James Kanze" <james.kanze (AT) gmail (DOT) com> writes:

Quote:
Jean-Marc Bourguet wrote:

Le retour covariant n'est qu'un moyen d'écrire

class BaseProperty {
public:
BaseProperty* type() { return type_(); }
protected:
virtual BaseProperty* type_() { return this; }
};

template <typename U
class Property: public BaseProperty {
public:
Property* type() { return static_cast<Property*>(type_()); }
protected:
BaseProperty* type_() { return this; }
};

Et ne change rien à la vision statique du code.

C'est une bonne façon de l'envisager, même si je crois que
l'implémentation la plus répandue correspond plutôt à :

template< typename T
class Property : public BaseProperty
{
public:
Property* type() { return this ; } ;
protected:
BaseProperty* type_() { return type() ; }
} ;

Ça ne fonctionne que s'il est garanti que les descendant retourne this,
auquel cas, on n'a même pas besoin des membres virtuels.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Back to top
James Kanze
Guest





PostPosted: Thu Oct 26, 2006 9:11 am    Post subject: Re: Un petit probleme de fonction virtuelle Reply with quote

Jean-Marc Bourguet wrote:

Quote:
Le retour covariant n'est qu'un moyen d'écrire

class BaseProperty {
public:
BaseProperty* type() { return type_(); }
protected:
virtual BaseProperty* type_() { return this; }
};

template <typename U
class Property: public BaseProperty {
public:
Property* type() { return static_cast<Property*>(type_()); }
protected:
BaseProperty* type_() { return this; }
};

Et ne change rien à la vision statique du code.

C'est une bonne façon de l'envisager, même si je crois que
l'implémentation la plus répandue correspond plutôt à :

template< typename T >
class Property : public BaseProperty
{
public:
Property* type() { return this ; } ;
protected:
BaseProperty* type_() { return type() ; }
} ;

(Et qu'évidemment, les fonctions virtuelles ne sont pas
protected, ni même pas private, mais complètement invisibles à
l'utilisateur.)

J'imagine que la raison tient aux cas où il y a l'héritage
virtuel : la conversion dérivée vers base va toujours, tandis
que la conversion base vers dérivée exige un dynamic_cast.

--
James Kanze (GABI Software) email:james.kanze (AT) gmail (DOT) com
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
James Kanze
Guest





PostPosted: Thu Oct 26, 2006 9:11 am    Post subject: Re: Un petit problème de fonction virtuelle Reply with quote

dieu.tout.puissant (AT) gmail (DOT) com wrote:
Quote:
Marc G wrote:
j'ai le code suivant :

class BaseProperty {
public :
virtual BaseProperty* type(void) { return this;}
int value(void) { return -1;}
};

// représente une propriété d'un certain type
template <typename U
class Property : public BaseProperty {
public :
Property(U* u) : _u(u) {}
virtual Property* type(void) { return this;}
U value(void) { return *_u; }
U* _u;
};

Mon problème :
j'ai lu qu'on pouvait changer le type de retour d'une fonction virtuelle
comme je le fais pour la fonction type
(et j'ai déjà utilisé avec succès cette faculté dans d'autres programmes)

Oui, car les types de retour de "type()" ont une relation d'héritage
publique. Property* est >>dérivée<< de BaseProperty*. C'est
uniquement dans ces cas-là que les types de retour (uniquement
pointeurs ou références) peuvent différer. Cela se nomme la
covariance des types de retour.

si j'écris :
int y=50;
Property<int> x(&y);
BaseProperty *xx=&x;
alors
xx->type()->value() vaut -1 et pas 50
pourquoi ?
normalement, type() retourne un pointeur Property<int>* et l'appel de
value() devrait valoir 50
le pb, c'est mon compilo ou moi Sad ?
en plus, si je regarde typeid(xx->type()).name(), j'ai BaseProperty * comme
réponse

Il faut se mettre à la place du compilateur.
Le type statique de *xx est BaseProperty. Le fait que son type
dynamique soit Property change simplement les pointeurs des fonctions
virtuelles.

En supposant que c'est comme ça que le compilateur implémente
les fonctions virtuelles. L'important, évidemment, c'est que de
telles expressions ont effectivement deux types, un type
statique, connu du compilateur, et un type dynamique, qui peut
varié lors de l'exécution. Ensuite, il faut savoir où le
compilateur utilise directement le type statique, et où il fait
une résolution dynamique. Et qu'en l'occurance, à l'encontre du
SmallTalk, le compilateur utilise toujours le type statique pour
la récherche des noms. (Sinon, l'expression serait légale même
si BaseProperty ne contenait pas de fonction value. Mais comment
alors est-ce que le compilateur pourrait savoir si le type
dynamique contenait une fonction du nom value ?)

[...]
Quote:
Donc si tu veux obtenir 50 et pas -1, il te suffit simplement de
déclarer "value()" virtual.

Sauf qu'évidemment, tout le but qu'il poursuit, c'est de
permettre au type de rétour de value() de varier de façon
arbitraire.

En fait, puisqu'il s'agit d'une dépendance dynamique, il faut
bien qu'il implémente quelque chose qui détermine le type
dynamiquement, et qui prévoir soit une erreur soit une
conversion supplémentaire s'il démande par exemple un double, et
le type dynamique est Property<int>. Je verrai bien quelque
chose du genre :

template< typename T > class Property ;

class BaseProperty
{
public:
class ReturnValue
{
public:
ReturnValue( BaseProperty* owner )
: myOwner( owner )
{
}

template< typename T >
operator T() const
{
return dynamic_cast< Property< T > const& >( *myOwner
).value() ;
}

template< typename T >
void operator=( T const& rhs ) const
{
dynamic_cast< Property< T >& >( *myOwner ).value() rhs ;
}

private:
BaseProperty* myOwner ;
} ;

ReturnValue value() ;
} ;

template< typename T >
class Property : public BaseProperty
// comme il a fait, plus ou moins, mais sans la fonction
// type.

Ce n'est pas parfait : pour faire marcher &xx->value(), il
faudrait surcharger l'operator& de ReturnValue pour qu'il
renvoie encore un proxy, et autant que je sache, ce n'est même
pas possible d'implémenter xx->value().unElementDeStruct. (On
peut, en revanche, supporter xx->value()->unElementDeStruct en
surchargeant l'operator-> de ReturnValue.)

--
James Kanze (GABI Software) email:james.kanze (AT) gmail (DOT) com
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
James Kanze
Guest





PostPosted: Thu Oct 26, 2006 9:11 am    Post subject: Re: Un petit problème de fonction virtuelle Reply with quote

Pierre Barbier de Reuille wrote:
Quote:
Marc G wrote:
j'ai le code suivant :

class BaseProperty {
public :
virtual BaseProperty* type(void) { return this;}
int value(void) { return -1;}
};

// représente une propriété d'un certain type
template <typename U
class Property : public BaseProperty {
public :
Property(U* u) : _u(u) {}
virtual Property* type(void) { return this;}
U value(void) { return *_u; }
U* _u;
};

Mon problème :
j'ai lu qu'on pouvait changer le type de retour d'une fonction virtuelle
comme je le fais pour la fonction type
(et j'ai déjà utilisé avec succès cette faculté dans d'autres programmes)

Je ne sais pas où tu as pu utiliser cette "possibilité" mais elle
n'est certainement normalisée !! Elle est même innimplémentable ...

Elle est bien normalisée, et elle est même implémenté, au moins
par g++ (et certainement par la plupart des autres
compilateurs). Je connais au moins deux implémentations
possibles.

Quote:
En effet, disons que tu as ce code :

struct A
{
virtual ~A() {}
virtual int f() { return 0; }
};

struct B : public A
{
virtual B& f() { return *this; }
};

Mais ce n'est pas ce qu'il a. Il a le cas où la valeur de retour
dans la classe de base est un pointeur à une base, et la valeur
de retour dans la dérivée est une dérivée. En principe, pour que
ça puisse marcher, il faut qu'il existe une conversion du type
de rétour dans la classe dérivée vers le type de rétour dans la
classe de base. Dans le cas de C++, la norme ne l'autorise que
si les deux types de rétour sont tous les deux des pointeurs ou
des références, et que le type désigné dans la classe dérivée
dérive du type désigné dans la classe de base.

--
James Kanze (GABI Software) email:james.kanze (AT) gmail (DOT) com
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
James Kanze
Guest





PostPosted: Thu Oct 26, 2006 9:11 am    Post subject: Re: Un petit problème de fonction virtuelle Reply with quote

Marc G wrote:
Quote:
j'ai le code suivant :

class BaseProperty {
public :
virtual BaseProperty* type(void) { return this;}
int value(void) { return -1;}
};

// représente une propriété d'un certain type
template <typename U
class Property : public BaseProperty {
public :
Property(U* u) : _u(u) {}
virtual Property* type(void) { return this;}
U value(void) { return *_u; }
U* _u;
};

Mon problème :
j'ai lu qu'on pouvait changer le type de retour d'une fonction
virtuelle comme je le fais pour la fonction type (et j'ai déjà
utilisé avec succès cette faculté dans d'autres programmes)

Certes, mais le typage reste statique. Tu n'as l'avantage du
type dérivé que si tu utilises des expressions de type Property.

Quote:
si j'écris :
int y=50;
Property<int> x(&y);
BaseProperty *xx=&x;
alors
xx->type()->value() vaut -1 et pas 50
pourquoi ?

Parce que value n'est pas virtuelle. L'expression xx->type()
renvoie bien un BaseProperty*, quelque soit le type de rétour
declaré de la fonction réelement appelée. (L'expression x.type()
renvoie bien un Property<int>*, en revanche.) Et puisque
BaseProperty::value() n'est pas virtuelle, c'est bien
BaseProperty::value() qui serait appelée.

Si tu y penses un peu, je crois que tu te rendras compte que ça
ne peut pas être autrement. Il faut bien que le compilateur
connaisse le type de l'expression xx->type(), afin de savoir où
chercher la fonction value() (dans ce cas précis). Et la seule
chose que le compilateur connaît, c'est bien le type static de
l'expression ; il ne peut pas savoir que xx va en fait désigner
un Property<int>. Il est donc obligé de chercher la fonction
dans BaseProperty, et de traiter la valeur de rétour de type
comme étant BaseProperty*.

Quote:
normalement, type() retourne un pointeur Property<int>* et l'appel de
value() devrait valoir 50

dynamic_cast< Property< int >* >( xx )->type()

renvoie un pointeur Property< int >*. xx->type() renvoie un
pointeur BaseProperty*, même si c'est exactement la même
fonction qui est appelée.

Quote:
le pb, c'est mon compilo ou moi Sad ?
en plus, si je regarde typeid(xx->type()).name(), j'ai BaseProperty * comme
réponse

Parce que le type renvoyé, c'est bien un BaseProperty*. Le type
dynamique qu'il pointe, en revanche, est un Property<int> ; si
tu fais typeid( *xx->type() ).name(), tu auras bien
Property<int>.

C'est exactement le même comportement que ce que tu aurais avec
xx tout court : typeid(xx).name() est BaseProperty*, mais
typeid(*xx).name() est Property<int>.

Quote:
mais si je définit la fonction type() pour qu'elle retourne des références,
typeid(xx->type()).name() vaut Property

Parce qu'il y a déréferencement automatique des références.

--
James Kanze (GABI Software) email:james.kanze (AT) gmail (DOT) com
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
Marc G
Guest





PostPosted: Thu Oct 26, 2006 9:11 am    Post subject: Re: Un petit problème de fonction virtuelle Reply with quote

Quote:
J'ai oublié de préciser que, dans ton code, tu peux déclarer
"value()" en virtual car x est un Property<int>, donc "value()" aura le
même type de retour dans Property et BaseProperty. Si tu utilises un
Property<double> par exemple, tu ne pourras plus déclarer "value()" en
fonction virtuelle.

oui, et c'est bien là mon problème. C'est précisement ce cas qui
m'intéresse.
Back to top
Marc G
Guest





PostPosted: Thu Oct 26, 2006 9:11 am    Post subject: Re: Un petit problème de fonction virtuelle Reply with quote

struct A
{
virtual ~A() {}
virtual int f() { return 0; }
};

struct B : public A
{
virtual B& f() { return *this; }
};

c'est uniquement valable quand f retourne un pointeur ou une référence sur
le type de la classe dans la hiérarchie
dans ton exemple, il y a conflit de fonctions virtuelles...
Marc
Back to top
Marc G
Guest





PostPosted: Thu Oct 26, 2006 9:15 pm    Post subject: Re: Un petit problème de fonction virtuelle Reply with quote

hélas, je n'ai pas réussi à faire marcher ton code pour obtenir un T comme
type de retour
voilà ce que j'ai recopié/légèrement modifié :

class BaseProperty {
public :
//--------------------------------------------------------------------------------------------
class ReturnValue {
public :
ReturnValue(BaseProperty* owner) : _owner(owner) {}
// opérateur de conversion en type T d'un objet ReturnValue
template<typename T>
operator T() const { return dynamic_cast< Property<T>&
Quote:
(*_owner).getvalue();}
// affectation d'un type T à un objet ReturnValue

template<typename T>
void operator=(T const& rhs) { dynamic_cast< Property<T>&
Quote:
(*_owner).getvalue()=rhs;}
private :

BaseProperty* _owner;
};
//--------------------------------------------------------------------------------------------
virtual ReturnValue value(void)=0;
};

template <typename T>
class Property : public BaseProperty {
public :
Property(T* t) : _t(t) {}
virtual ReturnValue value(void) { return ReturnValue(this); }
T getvalue(void) { return *_t; }
protected :
T* _t;
};

et après, j'ai pas compris ta surcharge de l'operator& de ReturnValue pour
qu'il
renvoie encore un proxy...

TypeObjet y=...;
Property<TypeObjet > x(&y);
BaseProperty *xx=&x;

et je cherche à obtenir d'une manière ou d'une autre un objet de type
TypeObjet à partir de xx
si j'écris xx->value(), j'ai un objet ReturnValue et je ne sais pas a
priori quelle est la bonne conversion...
même si (TypeObjet)xx->value() est ok, face à un objet ReturnValue, je ne le
sais pas !

Il y a t-il une solution à mon problème ?
Marc
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
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.