Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Référence de pointeur

38 réponses
Avatar
Stephane SOPPERA
Bonjour,

Je vous présente ici un petit souci que j'ai eu au travail.

Mettons que nous ayons la situation suivante:
class Base
{
public: virtual ~Base() {}
};

class Enfant1 : public Base
{
};

class Enfant2 : public Base
{
};

J'avais écrit une fonction du type:
void FreeBase ( Base *&p )
{
if ( NULL != p )
{
/* un traitement sur p ici */
....
/* fin du traitement */

delete p;
p = NULL;
}
}

Ainsi j'ai essayé d'utiliser:
Enfant1 *e1 = new Enfant1(...);
Enfant2 *e2 = new Enfant2(...);
...
FreeBase ( e1 );
FreeBase ( e2 );

malheureusement ça ne compile pas. L'erreur est quelque chose comme:
conversion impossible de Enfant1 * vers Base *&.

Est-ce que c'est vraiment impossible?
Suis-je obligé d'utiliser une méthode template dans ce cas là? (ce qui
m'est impossible, les templates m'étant interdits)

Je ne suis pas satisfait par le copier/coller que j'utilise pour l'instant.

Merci d'avance,

--
Stephane SOPPERA
http://perso.wanadoo.fr/stephane.soppera

10 réponses

1 2 3 4
Avatar
Jonathan Mcdougall
Oui. Un "Enfant1*" n'est _pas_ un "Base*", donc une conversion de
"Enfant1*" vers "Base*" passe par une copie du pointeur. Si tu passes
cette copie par référence, seule la copie sera modifiée, et comme elle
est temporaire, la modification n'est pas visible. D'où
l'interdiction, parce que ça n'a aucun sens.


Peux-tu essayer de le dire en d'autres termes, car je ne saisis
toujours pas.


Jonathan

Avatar
Fabien LE LEZ
On Wed, 30 Jul 2003 20:33:32 +0200, "Stephane SOPPERA"
wrote:

Est-ce que c'est vraiment impossible?


Oui. Un "Enfant1*" n'est _pas_ un "Base*", donc une conversion de
"Enfant1*" vers "Base*" passe par une copie du pointeur. Si tu passes
cette copie par référence, seule la copie sera modifiée, et comme elle
est temporaire, la modification n'est pas visible. D'où
l'interdiction, parce que ça n'a aucun sens.

Suis-je obligé d'utiliser une méthode template dans ce cas là? (ce qui
m'est impossible, les templates m'étant interdits)


Laisse-moi deviner : tu es un fan inconditionnel de Napoléon, et tu as
donc décidé d'utiliser le même compilateur C++ que ses ingénieurs
utilisaient à l'époque ? ;-)

Si tu ne peux pas utiliser les templates, utilise ce qui existait
avant : les macros.

void FreeBase_appel_par_macro ( Base *p )
{
if ( NULL != p )
{
/* un traitement sur p ici */
....
/* fin du traitement */

delete p;
}
}

#define MACRO_FreeBase(p) { FreeBase_appel_par_macro (p); p= 0; }



--
Tout sur fr.* (FAQ, etc.) : http://www.usenet-fr.net/fur/
et http://www.aminautes.org/forums/serveurs/tablefr.html
Archives : http://groups.google.com/advanced_group_search
http://www.usenet-fr.net/fur/usenet/repondre-sur-usenet.html

Avatar
Fabien LE LEZ
On Wed, 30 Jul 2003 07:54:33 -0400, Jonathan Mcdougall
wrote:

Peux-tu essayer de le dire en d'autres termes, car je ne saisis
toujours pas.


Soit le code suivant :

void f (double d);

int i= 3;
f (i);

La fonction f(int) n'existe pas ; la fonction la plus proche est
"f(double)". Il faut donc convertir l'entier "i" en double.

la ligne "f(i);" est donc équivalente à

{
double temp (i);
f (temp);
}

Jusque-là, pas de problème : une variable temporaire de type "double"
est créée ; on lui assigne la valeur de i ; f est appelée avec cette
variable temporaire ; la variable temporaire est détruite.


Prenons maintenant le code suivant :

void g (double& d);
int i= 3;
g (i);

Même principe : une variable temporaire de type "double" est créée ;
on lui assigne la valeur de i ; g est appelée avec cette variable
temporaire ; la variable temporaire est détruite.
Et "i" dans tout ça ? Ben, sa valeur n'est pas modifiée, contrairement
à ce qu'on pourrait croire en écrivant "g(i);".
C'est pour ça que cette construction est interdite.

Pour revenir à ton problème, remplace "int" par "Enfant1*" et "double"
par "Base*".


--
Tout sur fr.* (FAQ, etc.) : http://www.usenet-fr.net/fur/
et http://www.aminautes.org/forums/serveurs/tablefr.html
Archives : http://groups.google.com/advanced_group_search
http://www.usenet-fr.net/fur/usenet/repondre-sur-usenet.html

Avatar
kanze
"Stephane SOPPERA" wrote in message
news:<bg936l$1kh$...

Je vous présente ici un petit souci que j'ai eu au travail.

Mettons que nous ayons la situation suivante:
class Base
{
public: virtual ~Base() {}
};

class Enfant1 : public Base
{
};

class Enfant2 : public Base
{
};

J'avais écrit une fonction du type:
void FreeBase ( Base *&p )
{
if ( NULL != p )
{
/* un traitement sur p ici */
....
/* fin du traitement */

delete p;
p = NULL;
}
}

Ainsi j'ai essayé d'utiliser:
Enfant1 *e1 = new Enfant1(...);
Enfant2 *e2 = new Enfant2(...);
...
FreeBase ( e1 );
FreeBase ( e2 );

malheureusement ça ne compile pas. L'erreur est quelque chose comme:
conversion impossible de Enfant1 * vers Base *&.


Je l'espère bien. Un Enfant1* n'est pas un Base*. Il faut bien une
conversion (qui pourrait changer des bits dans la représentation).

Est-ce que c'est vraiment impossible?


Impossible, non. Autrefois, c'était légal. C'est même encore le cas avec
beaucoup de compilateurs, pour des raisons de compatibilité
ascendante.

On l'a interdit parce que la sémantique était trompeur. En particulier,
quand c'est légal, ta fonction FreeBase( e1 ) ne modifie pas e1.

Suis-je obligé d'utiliser une méthode template dans ce cas là? (ce qui
m'est impossible, les templates m'étant interdits)


Est-ce que tu es obligé à utiliser une fonction aussi inutile ?

Je ne suis pas satisfait par le copier/coller que j'utilise pour
l'instant.


Si tu utilises du copier/coller, je comprends ta frustration. Mais pour
l'instant, je ne vois pas l'intérêt de la fonction ; je dirais alors de
la virer carrément, pour encore plus de simplicité.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

Avatar
Stephane SOPPERA
Est-ce que c'est vraiment impossible?


Impossible, non. Autrefois, c'était légal. C'est même encore le cas avec
beaucoup de compilateurs, pour des raisons de compatibilité
ascendante.

On l'a interdit parce que la sémantique était trompeur. En particulier,
quand c'est légal, ta fonction FreeBase( e1 ) ne modifie pas e1.

Effectivement, je viens de comprendre pourquoi mon codé était stupide ;-)

En fait ce n'est pas plus mal que ça n'ai pas compilé en fait.

Suis-je obligé d'utiliser une méthode template dans ce cas là? (ce qui
m'est impossible, les templates m'étant interdits)


Est-ce que tu es obligé à utiliser une fonction aussi inutile ?


Pourquoi cette fonction est inutile? Je ne vois pas bien...

Je ne suis pas satisfait par le copier/coller que j'utilise pour
l'instant.


Si tu utilises du copier/coller, je comprends ta frustration. Mais pour
l'instant, je ne vois pas l'intérêt de la fonction ; je dirais alors de
la virer carrément, pour encore plus de simplicité.


Par exemple, j'ai dans la class implémentant la méthode FreeBase trois
pointeurs vers des classes Enfant1 et deux vers des classes Enfant2. Ces
classes sont des ressources (des textures en fait) qui peuvent être non
assignées (NULL), ou remplacées au cours de l'éxécution indépendament les
unes des autres. J'ai donc un code de libération de resource qui va être
le même pour chaque resource (que ce soit une classe Enfant1 ou Enfant2
car la libération de la ressource n'utilise que de méthode de leur parent
commun). Or je voulais éviter d'écrire 5 fonctions différentes pour
libérer chacune des resources une à une alors que le code était absolument
identique pour chacune de ces fonctions (seul le nom du pointeur
changeant).
Cette fonction correspond donc à une "factorisation" de mon code.

--
Stephane SOPPERA
http://perso.wanadoo.fr/stephane.soppera


Avatar
Stephane SOPPERA
Suis-je obligé d'utiliser une méthode template dans ce cas là? (ce qui
m'est impossible, les templates m'étant interdits)


Laisse-moi deviner : tu es un fan inconditionnel de Napoléon, et tu as
donc décidé d'utiliser le même compilateur C++ que ses ingénieurs
utilisaient à l'époque ? ;-)


Non, je travaille dans une grosse boite qui produit un logiciel
multi-plateformes et qui a décidé de banir les templates.

Si tu ne peux pas utiliser les templates, utilise ce qui existait
avant : les macros.


Je préfère écrire deux fois la même fonction ;-) Une pour Enfant1*& et
l'autre pour Enfant2*&, même si au final c'est un peu dommage.

Merci pour ta réponse!

--
Stephane SOPPERA
http://perso.wanadoo.fr/stephane.soppera


Avatar
Fabien LE LEZ
On Thu, 31 Jul 2003 18:42:10 +0200, "Stephane SOPPERA"
wrote:

Cette fonction correspond donc à une "factorisation" de mon code.


Ben oui, c'est pour ça que les templates ont été inventés ;-)


--
Tout sur fr.* (FAQ, etc.) : http://www.usenet-fr.net/fur/
et http://www.aminautes.org/forums/serveurs/tablefr.html
Archives : http://groups.google.com/advanced_group_search
http://www.usenet-fr.net/fur/usenet/repondre-sur-usenet.html

Avatar
Fabien LE LEZ
On 31 Jul 2003 19:02:10 +0200, Gabriel Dos Reis
wrote:

| Non, je travaille dans une grosse boite qui produit un logiciel
| multi-plateformes et qui a décidé de banir les templates.

est-ce une décision technique ? Politique ?


Ça me rappelle furieusement le "this->" imposé pour toute utilisation
de variable membre...


--
Tout sur fr.* (FAQ, etc.) : http://www.usenet-fr.net/fur/
et http://www.aminautes.org/forums/serveurs/tablefr.html
Archives : http://groups.google.com/advanced_group_search
http://www.usenet-fr.net/fur/usenet/repondre-sur-usenet.html

Avatar
Stephane SOPPERA
| Non, je travaille dans une grosse boite qui produit un logiciel
| multi-plateformes et qui a décidé de banir les templates.

est-ce une décision technique ? Politique ?


En fait je n'ai pas encore pu le savoir. Et je n'ai pas encore rencontré
de gens qui savaient ;-)

--
Stephane SOPPERA
http://perso.wanadoo.fr/stephane.soppera

Avatar
Stephane SOPPERA
On Thu, 31 Jul 2003 19:00:07 +0200, Fabien LE LEZ wrote:

On Thu, 31 Jul 2003 18:47:05 +0200, "Stephane SOPPERA"
wrote:

Si tu ne peux pas utiliser les templates, utilise ce qui existait
avant : les macros.


Je préfère écrire deux fois la même fonction


Pourquoi ?


Parcque je préfère éviter à tout prix les macros, que je n'ai que deux
classes Enfants, et que le code est relativement court (quelques lignes).


--
Stephane SOPPERA
http://perso.wanadoo.fr/stephane.soppera



1 2 3 4