1

Salut,

Problème du jour: B dérive de A
Soit f une fonction au prototype suivant: void f(A *&toto);
La création de B se fait de la manière suivante: B::create();

Comment passer un objet B à f tout en pouvant l'utiliser en temps qu'objet de type B dans le reste de la fonction appelante.



Solution crade trouvée:

B* pi = B::Create();
A* you = pi;

f(you);

B->coucouToto();



EDIT: erreur dans l'énoncé

2

Pourquoi tu voudrais faire ça, un B* renvoyé par B::create() n'est pas du tout un A* ?

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

3

Attention il faut chercher un peu, on rentre dans la grande subtilité du C++ wink

4

Je me suis bien dit que tu t'étais planté de sens mais même dans ce sens-là je vois pas trop le problème : f peut très bien remplacer toto par un A* quelconque qui serait pas un B*, donc c'est normal que tu doives passer par A* plutôt que B* confus

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

5

Effectivement. Il y a une référence non-const, ce qui permet à la fonction de modifier le pointeur.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

6

je précise le problème:
Il n'est pas possible de passer directement pi

7

Et Pollux a expliqué pourquoi.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

8

heu il me semble que ce n'est pas la bonne explication.
f(A* toto); on peut tres bien passé B alors et cela peut etre remplacé par C.
Soit je n'ai pas compris la reponse soit ce n'est pas la reponse.

9

Ce qu'ils essayent de t'expliquer c'est que tu as une référence vers un pointeur de type A*.
[paraphrase mode=on]Comme Kevin l'a dit ta référence n'est pas constante, ce qui veut dire que ta fonction f(A* &toto) peut modifier toto, or ta fonction identifie toto comme étant de type A*, ce qui veut dire que si toto devait être modifié, f y mettrait certainement une valeur de type A*, qui pourrait être de type B* mais qui pourrait aussi ne pas l'être.
Mais puisque le compilateur sait que pi est de type B*, il ne veut pas t'autoriser à mettre n'importe quelle valeur de type A* dedans...[/paraphrase]
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

10

ok donc le problème n'a pas lieu si on met un const.
Cela m'embete grandement les gens qui utilisent ce genre de chose, cela casse tout polymorphisme propre (sans dynamic cast etc.).

L'art de faire compliquer pour rien...

Merci pour l'explication wink

11

dites, c'est quoi l'intéret d'avoir un pointeur vers une référence, ou l'inverse?

d'ailleurs c'est codé comment une ref? comme un pointeur, mais "on le sait pas" ?

12

Justement, ça sert à permettre à la fonction appelée de modifier le pointeur. En revanche, une référence const vers un pointeur ne sert strictement à rien, il vaut mieux passer le pointeur par valeur tout simplement, c'est plus efficace.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

13

C'est juste pour le const.
Ce genre de fonction n'est pas forcement le bon exemple hein, mais le problème c'est que l'on choisit pas forcement les fonctions que l'on utilise lol.
On voit vite que ce genre de fonction est limité, c'est l'équivalent d'une pauvre factory sans avantage et avec les inconvénients.

14

15

-trop +mal ^^

(en fait je ne comprends pas trop le problème, Pollux a parfaitement expliqué en ./4 pourquoi l'erreur obtenue était tout à fait logique, et je ne vois pas le rapport entre ça et la dernière phase du ./13)
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

16

Non mais j'ai dit que c'était bon pour la réponse smile
Ma critique venait du fait que cela empêchait de passer une classe dérivé sans cast immonde... alors qu'il suffisait de prendre une ref en entrée et en ressortir une en sortie.
Dans tout les cas on se retrouve de toute manière face a un design qui ne me plait pas.


17

ok ^^
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

18

Et juste en conclusion à ton exemple :
JackosKing (./1) :
Solution crade trouvée:

B* pi = B::Create();
A* you = pi;

f(you);
B->coucouToto();


=> cette "solution" va se planter lamentablement d'objet si la fonction f modifie you... et que la dernière ligne était supposée prendre en compte les effets de bord de f.

19

oui, tout à fait smile
En fait je me fais meme plus chier j'utilise pas cette fonction, elle sux :P

20

ah, ça me fait chaud au coeur que tu reviennes à du code plus simple smile

21

ce n'etait pas ma fonctionwink
C'est comme je vois du code avec des pointeur de fonction membre ca fait peur...

22

encore un préjugé à la con, y'a tout un tas de cas où c'est une solution parfaitement adaptée hehe
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

23

lol je pense surtout que ya tout un tas ou les functors suffisent largement wink Sans compter le nombre de fois ou cela peut provenir d'une erreur de design!

24

25

Un "objet fonction" (un objet qui va redéfinir l'opérateur () et pouvoir être appelé comme une fonction). C'est un truc utile aussi, mais qui ne remplace absolument pas les pointeurs sur membre selon moi (ne serait-ce que parceque ça n'a rien à voir et que ça ne s'utilise pas pour les mêmes problématiques).
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

26

Bein la diff c'est la visibilité des attributs d'une classe. Apres ca depend beaucoup du design que tu fais...

27

Avant même de dépendre du design ça dépend surtout de ce qu'on cherche à faire; si c'est pour les utiliser au sein d'une même classe, la question de l'encapsulation ne se pose même pas.
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

28

pour moi l'utiliser au sein d'une meme class est typiquement une consequence d'un choix au niveau du designwink

29

Bah non, le design n'est là que pour répondre à un besoin qui se présente nécessairement avant pour moi. Je vois difficilement comment on peut se demander quel design utiliser avant de savoir ce qu'on veut faire :/ (conception préliminaire vs conception détaillée si tu veux une comparaison avec les phases de développement logiciel)
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

30

Je ne vois pas cela comme une conception détaillée, mais juste une reflection utile, qui peut se poser meme en faisant du TDD en écrivant ton TU.
En effet soit tes fonctions sont dans ta class soit elles sont externalisée dans d'autres classes. Probleme de responsabilité de la classe, que doit elle faire, doit elle etre extensible etc. J'admets que si tu veux utiliser les fonctions qui sont dans ta classe avec un prototype identique, cela peut sembler etre un cas d'utilisation de pointeur de methode, mais avant de trouver la solution je me serais plutot posé la question si ces fonctions doivent etre dans la classe (forte cohesion) ou dans des classes functors (faible couplage?).
Le lien de cohesion/couplage etant pour moi directement dependant de l'utilisation ou non des attributs privés non-accessible par setter/getter.