Je ne risque pas d'avoir un problème concernant la recopie avec le vector? (cf message Luc)
Cette solution me convient en tous cas!!!!
Je ne risque pas d'avoir un problème concernant la recopie avec le vector? (cf message Luc)
Cette solution me convient en tous cas!!!!
Recopie ? Si tu copies ce vecteur dans un autre, tu ne copieras que pointeur intelligent, pas l'objet pointé.
OK ok, je crois qu'en fait j'avais mal compris l'explication de Luc (vivement les vacances): http://www.developpez.net/forums/sho...&postcount=177
Donc un vector<CFP*> ça doit marcher? On peut recopier un pointeur quand même?
Si ça marche, quels seraient les avantages d'utiliser boost?
Pardon pour toutes ces questions, et un grand merci pour la patience...
oui, on peut copier des pointeurs
L'avantage ? C'est que s'il y a un problème, tu n'oublieras pas d'effacer la mémoire allouée.
Ouf !Envoyé par Miles
Hum...L'avantage ? C'est que s'il y a un problème, tu n'oublieras pas d'effacer la mémoire allouée.
Là dessus j'ai une question toute bete: j'ai un vecteur de 3 CFP*. Je souhaite supprimer l'élément du milieu.
Si je fais:
je fais une fuite de mémoire.
Code : Sélectionner tout - Visualiser dans une fenêtre à part tableau_cfp[1] = NULL
Si je faisc'est ok?
Code : Sélectionner tout - Visualiser dans une fenêtre à part tableau_cfp[1]->~CFP()
Je ne vois pas d'autre manière, avec mon oeil débutant, de libérer la mémoire qu'en appelant explicitement le destructeur?
D'ou le boost::shared_ptr, c'est ça Miles?
Ca serait plutôt :
L'appel au destructeur ne libère pas la mémoire.
Code : Sélectionner tout - Visualiser dans une fenêtre à part delete tableau_cfp[1];
Et effectivement, les pointeurs intelligents permettent de passer outre ce petit problème.
super! J'ai tout compris!
Au fait, y a t il besoin de faire un cast d'un objet fils vers un objet mère?
Ici cfp devrait être de type CFP* ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 void Choc::ajouterComposant(std::string nom_cfp) { if (isLPT(nom_cfp) ) { LPT *cfp = new LPT(*this, nom_cfp); } Antenne *cfp = new Antenne(*this, nom_cfp); tableau_cfp.push_back(cfp); }
Est-ce automatique?
Ou bien in faut un static_cast?
Tu peux mettre directement CFP, il y a un cast implicite possible si le cast va vers les parents.
Euh, c'est pas plutot camera (c minuscule)Envoyé par poukill
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 CFP::CFP(Choc & c, std::string nom_cfp) : m_choc(c), nom_composant(nom_cfp), camera(c, nom_cfp) { std::cout << "Creation d'un objet CFP"<< std::endl; zone = 0; setImageVisible(); setImageIR(); ajusterTailleVisibleEtIR(); }
Avant de poser une question, lire la Avant de répondre, lire la question
Tant que tu ne stockes qu'un pointeur/référence pour plus tard, je n'ai encore jamais eu de problèmes. J'imagine que l'accès aux membres déjà construits passe aussi de même que l'appel aux fonctions membres non virtuelles (reposant sur des données construites)Envoyé par Miles
1- Bien sûr. C'est comme cela que l'on fait d'ailleurs.1) Le construteur d'une classe fille peut-il appeler le constructeur de la classe mère abstraite?
2) Concernant le message de Luc sur mes vector: quelle solution adopter:
a) Prendre un autre conteneur (liste ?)
b) Utiliser un new/ delete[] (passage par pointeur)
2- Je préfère systématiquement les conteneurs à la gestion manuelle de la mémoire. Je ne me rabats vers cette dernière que pour mettre en oeuvre des algos et autres TAD bas niveaux comme ... des conteneurs qui m'offrent des services que ceux standard ne m'offrent pas.
Il y a toujours un constructeur dans une classe. Ne serait-ce que celui dit "constructeur par défaut". Après idéalement certains préconisent qu'une classe abstraite n'ait pas de données. D'un point de vue design, on rejoint les notions d'interfaces. Parfois, on est préssés. Parfois un design hybride suffit, voire est plus précis. Du coup, on se retrouve avec des classes abstraites qui servent à implémenter (/réutiliser) (et pas seulement à être substituées) et qui ont des données membres. Ce qui rend nécessaire la présence de constructeurs .. qui doivent impérativement être appelés.C'est quand même bizarre: une classe abstraite ne peut etre instancié, mais possède quand même un constructeur... No comment!
Pas comme ça. Et jamais.Là dessus j'ai une question toute bete: j'ai un vecteur de 3 CFP*. Je souhaite supprimer l'élément du milieu.
Si je fais:
je fais une fuite de mémoire.
Code : Sélectionner tout - Visualiser dans une fenêtre à part tableau_cfp[1] = NULL
Si je fais
c'est ok?
Code : Sélectionner tout - Visualiser dans une fenêtre à part tableau_cfp[1]->~CFP()
Je ne vois pas d'autre manière, avec mon oeil débutant, de libérer la mémoire qu'en appelant explicitement le destructeur?
Effectivement, tu as une fuite de mémoire dans le premier cas.
La seconde écriture ... <hynopse>Elle n'existe pas</>. Je jour où tu sauras quand t'en servir, tu sauras qu'un code "métier" ne doit jamais contenir de choses pareilles. C'est réservé à des traitements très bas niveaux comme ... la définition d'une classe vecteur.
Bref. Retiens que si tu alloues avec new. Alors implicitement tu as construit. (pas le cas du malloc qui ne construit pas)
Pour libérer, le pendent c'est delete qui, les choses sont bien faites, détruit.
La version boost.shared_ptr, c'est pour être sûr de toujours faire un appel au delete quelque soit le chemin que prendra ton code. C'est en gros la façon la plus simple pour obtenir du code simple à maintenir qui résiste aux exceptions. Tu as un gros pan de la FAQ qui en traite.
Tu fais le new, le delete sera fait pour toi au moment oppurtun.
Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...
Tout à fait harsh... Je l'avais corrigé, mais merci à toiEnvoyé par harsh
Ok Luc, merci pour ces précisions (toujours aussi pertinentes )
Je vais m'orienter sur un vector, car je ne connais pas le nombre d'élement au départ. Par contre, je ne pense pas finalement utiliser boost car l'utilisateur seul sait quand enlever ou rajouter un CFP.
Je me lance maintenant dedans! J'espère aboutir avant de partir en week end! (c'est pas gagné )
Merci à tous!
Re bonjour à tous!
J'ai deux problèmes assez fin (je pense!) à résoudre :
1)Dans ma classe CFP je récupère une référence à Choc:
CFP possède une instance privée d'une classe Camera (en gras)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 class CFP { public: CFP(Choc & c, std::string nom_cfp); ~CFP(); CImg <unsigned short> getImageIR(); virtual setImageIR(CImg <unsigned short>) = 0; CImg <unsigned short> getImageVisible(); void setImageVisible(); void ajusterTailleVisibleEtIR(); std::string getNomComposant(); private: Camera camera; CImg <unsigned short> image_IR_ref; CImg <unsigned short> image_visible; std::string nom_composant; int zone; Choc & getChoc() {return m_choc; } Choc const& getChoc() const {return m_choc; } int getChocNum() const; Choc & m_choc; // référence => on ne change pas de contexte! }
Camera a besoin d'une référence à Choc. Ai-je besoin d'exporter aussi une référence, ou bien Camera peut récupérer cette contenu dans CFP???
2) Comme Camera est une instance privée, comment accéder aux méthodes publiques de camera? En redéfinissant des méthodes publiques dans CFP? Ca va me pourrir l'interface?
Merci d'avance pour vos réponses!
Le deuxième problème se généralise assez bien et me pose encore plus de pbs que je ne pensais : lorqu'on place une instance de classe en private: comment utiliser ses méthodes? sans modifier l'interface?
Tu veux dire : est-ce que l'on peut accéder aux méthodes d'un objet privé si on connait l'objet qui le contiens ? (par exemple, si on a un objet de classe CFP, est-ce que l'on peut accéder aux méthodes de son objet Choc ?)Envoyé par poukill
Le réponse est non : pas directemement.
Pour pouvoir accéder aux méthodes, il faut avoir accès à l'objet. Donc, soit tu déclares l'objet public (ou private si tu veux que seuls les descendants puissent y avoir accès), soit tu déclare la classe qui doit pouvoir y accéder comme friend (dans ce cas, elle peux accéder directement à tous les membres privés de ta classe), soit tu change ton interface en y ajoutant des accesseurs...
Et pour le 1) : Camera a besoin d'une référence à Choc. Ai-je besoin d'exporter aussi une référence, ou bien Camera peut récupérer cette contenu dans CFP???
camera ne peut pas avoir accès au choc de CFP, puisque le choc de CFP est privé (il est inaccessible en dehors de ta classe CFP).
Si ton objet contient une caméra,cela veut dire que qulques part il en est responsable.
S'il n'est responsable que du cycle de vie da ta caméra, alors peut-être peux-tu exposer une accesseur vers ta caméra.
S'il est responsable de bien plus de choses, alors pourquoi ne fournirait-il pas le service que l'appelant voudrait exécuter sur la caméra ?
Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...
Salut!
Merci à Luc et Eusebe. J'ai pour l'instant encore du mal à séparer interface et implantation. D'où les difficultés de partage de données membres... Tout va bientôt se régler je pense.
Une question plutôt de programmation propre: est-ce que le fait de mettre un accesseur (ici getTableauCFP() ) qui renvoi un objet private non const constitue une mauvaise idée de programmation?
De cette façon, on récupère la copie d'n objet, or j'aurai besoin d'appeler des méthodes dans CFP, et que tout ceci soit quand même correctement stocké dans Choc.
J'ai pensé au passage par référence, mais sur un membre privé, ça fait vraiment sale.
Peut-être la meilleure solution est de déclarer tableau_cfp public? Comme ça le main pourra faire ses bidouilles.
Plus je programme Objet, plus je me rend compte qu'on minimise l'effort, mais que mes classes principales (Choc et CFP) vont bientôt se retrouver avec plein de méthode qui vont pourrir l'interface...
Bref, ma question pourrait d'énoncer ainsi : comment retrouver de l'action au sein de classe de petite échelle avec toutes ces compositions?
Le fait que je pose la question est-il un signe de couplage fort entre mes classes?
Merci beaucoup
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 class Choc { public: Choc (int num_choc, std::string nom_cfp); ~Choc(); void ajouterComposant(CFP*); void ajouterLPT(std::string); void ajouterAntenne(std::string); void supprimerComposant(std::string); std::vector <CFP*> getTableauCFP(); int getNumeroChoc (); private: std::vector <CFP*> tableau_cfp; int numero_choc; }
Moi, ça ne me choque pas !Envoyé par poukill
Tu feras alors la copie du tableau, mais comme ce tableau contiens des pointeurs, il n'y aura pas de problème : les CFP modifiés seront les mêmes que ceux stockés dans ta classe Choc.
Pour le reste, je ne suis pas encore assez savant pour te répondre
Tu vas rire! J'ai oublié que c'était des pointeurs !
Un get convient tout à fait!
Le seul truc que je pourrai pas controler, c'est si on fait des push_back()... M'enfin, je peux pas tout avoir...
Merci bcp Eusebe!
Je suis preneur d'autres avis éventuellement!
@Luc: J'ai effectivement mis des méthodes dans CFP qui appelles des routines dans Camera, et c'est très bien comme ça!
Avoir un accès non contant vers une donnée privée, cela veut un peu dire que la donnée n'a pas à être privée.
Il m'arrive de faire de telles choses. Mais je passe avant du temps à voir si les accès que je veux réaliser ne correspondent pas en fait à un nombre restreint de fonctions qui devraient être au niveau de l'objet directement englobant, ou si la donnée doit vraiment être stockée à cet endroit.
Bref, je n'ai pas de recette miracle.
Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager