Question sur la programmation C++

Question sur la programmation C++ - C++ - Programmation

Marsh Posté le 02-10-2005 à 18:21:44    

Bonjour,
 
voilà je suis en train d'apprendre la programmation c++ et il y a diverses choses que je ne comprends pas :  
 
- quand passe-t-on un argument par référence a une fonction? desfois dans les corrections ils le font alors que l'argument n'est pas modifié :??:
meme question quand on retourne une référence avec les fonctions  
 par exemple pour la surcharge de l'opérateur =
il retourne une référence et ils passent l'argument a droite (donc celui qui n'est pas modifié) par reference
 
- quand déclare-t-on une fonction amie a une classe? j'ai bien compris que cela servait a ce que la fonction ait accès aux parties privées de la classe mais je doute quon le fasse systématiquement (sinon a quoi bon déclarer des méthodes ou des attributs en private)
 
- comment choisir si une méthode doit etre définit a l'intérieur ou a l'extérieur d'une classe ?
 
 
merci d'avance pour votre aide
 
 :hello:

Message cité 1 fois
Message édité par Profil supprimé le 02-10-2005 à 18:24:53
Reply

Marsh Posté le 02-10-2005 à 18:21:44   

Reply

Marsh Posté le 02-10-2005 à 20:55:18    


 
 
Salut, moi aussi je suis en train d'apprendre mais je peux peut etre t'apporter quelques réponses.
 
- On fait ça pour des paramètres de type class (ou struct). Quand tu passe un élément à une fonction par valeur, au sein de la fonction une variable interne de même type est recrée et la valeur du premeir element est recopiée dans le second. Si t'as une classe avec une dizaine d'attributs, ca prend de la place en mémoire pour rien durant l'execution de ta fonction. Ainsi, on lui passe juste son adresse (beaucoup plus leger), par le passage de paramètres par reference.
Il ne faut absolument pas voir ca comme si on voulait modifier l'element initial ! (par exemple si la fonction retourne déja autre chose). Il est tout à fait possible de voir void mafonc(const maclasse & nomvar) (la c'est clair qu'on veut pas le modifier).
 
- Les fonctions amies c'est pas bien  :non: . Donc non, on ne le fait pas systematiquement. Si une classe a des attributs de type une autre classe, alors il faut voir du coté des objets emboités.
 
- Une methode est toujours déclarée à l'interieur d'une classe. Sinon c'est une fonction.
 
Voila, j'espere avoir été clair  :hello:


Message édité par mcyrb le 02-10-2005 à 20:55:44
Reply

Marsh Posté le 02-10-2005 à 20:58:14    

Citation :

- quand passe-t-on un argument par référence a une fonction? desfois dans les corrections ils le font alors que l'argument n'est pas modifié :??:


 
quand on veut pas en faire une copie (c'est a dire, tres souvent pour les types non primitifs)
 

Citation :

meme question quand on retourne une référence avec les fonctions


 
generalement c'est qu'on renvoie une variable membre. On colle (d'ailleurs on renvoie une reference "const" )
 

Citation :

- quand déclare-t-on une fonction amie a une classe? j'ai bien compris que cela servait a ce que la fonction ait accès aux parties privées de la classe mais je doute quon le fasse systématiquement (sinon a quoi bon déclarer des méthodes ou des attributs en private)


 
a peu pres jamais
 

Citation :

- comment choisir si une méthode doit etre définit a l'intérieur ou a l'extérieur d'une classe ?


 
c'est ton design, ca. Ca viendra avec le temps et les gamelles :d
 

Reply

Marsh Posté le 02-10-2005 à 21:25:01    

Tu passes par référence quand il s'agit d'objet que tu as créé toi même (tes propres classes par exemple).
Tu passes par adresse quand il s'agit de int, float, double, char, etc... et que tu dois modifier la valeur dans la méthode
Tu passes par valeur quand tu ne dois pas modifier la valeur (int, float, double, char, etc...)
 
Enfin c'est les règles de bonnes pratiques qu'on apprend à l'école et dans les livres.  
Mais en pratique, sincèrement je préfère de loin les pointeurs que les références en C++.
 
Par contre, dans d'autre langage comme le C# et le JAVA, il n'existe plus que des références. Enfin il y a encore des pointeurs, mais c'est plus si facile de les utilisés car il faut mettre diverses choses en place pour les exploiter...

Message cité 1 fois
Message édité par moi23372 le 02-10-2005 à 21:25:46
Reply

Marsh Posté le 02-10-2005 à 21:28:32    

moi23372 a écrit :


Par contre, dans d'autre langage comme le C# et le JAVA, il n'existe plus que des références.


nan [:pingouino] ca ressemble plus a des pointeurs
 
 

Reply

Marsh Posté le 02-10-2005 à 21:35:52    


Citation :

- quand passe-t-on un argument par référence a une fonction? desfois dans les corrections ils le font alors que l'argument n'est pas modifié :??:


 
Si je comprend bien ta question, tu voudrais un passage d'argument par référence constante ? Tu as sans doute raison, si l'argument n'est pas modifié.
 

Citation :

meme question quand on retourne une référence avec les fonctions  
 par exemple pour la surcharge de l'opérateur =
il retourne une référence et ils passent l'argument a droite (donc celui qui n'est pas modifié) par reference


 
Foo & operator=( Foo const & ); normalement
 

Citation :

- quand déclare-t-on une fonction amie a une classe? j'ai bien compris que cela servait a ce que la fonction ait accès aux parties privées de la classe mais je doute quon le fasse systématiquement (sinon a quoi bon déclarer des méthodes ou des attributs en private)


 
pour surcharger des operateurs non membre, comme l'inserteur ou l'extracteur (<<, >>, ...), ça a un sens.
Meme si d'autre te dirons peut etre, c'est la mal, t'as qu'a faire une fonction membre publique print() et l'operateur (inline) appelle print(). Je trouve ça inélégant au possible.
 

Citation :

- comment choisir si une méthode doit etre définit a l'intérieur ou a l'extérieur d'une classe ?


si tu *defini* une fonction membre à l'interieur d'une classe, celle-ci est implicitement inline. Ce n'est généralement pas souhaitable, sauf peut-etre dans le cas de fonctions tres courtes comme les accesseurs par exemple.
 

Reply

Marsh Posté le 02-10-2005 à 21:51:57    

oups attendez je crois que j'ai confondu définit et déclarer
 
comment choisir si on déclare la fonction a lintérieur ou a l'extérieur de la classe?
 
il me semble que la plupart du temps on declare a l'intérieur et on définit a l'extéireur
 
mais desfois on fait le tout a l'extérieur
comment choisir?

Reply

Marsh Posté le 02-10-2005 à 22:07:01    


 
Si ta fonction n'a pas besoin d'avoir l'acces aux membres privés ou protégés de ta classe, fais en une fonction libre, non friend. (pas le cas le plus courant)
Dans le cas contraire, fais en une fonction membre.
Et enfin, certaines surcharges d'operateurs ne peuvent pas etre défini en tant que membre, mais ont besoin des membres protégés ou privés de ta classe. A ce moment la, fais en une fonction libre, friend.

Reply

Marsh Posté le 02-10-2005 à 22:31:58    

++fab a écrit :

Et enfin, certaines surcharges d'operateurs ne peuvent pas etre défini en tant que membre, mais ont besoin des membres protégés ou privés de ta classe. A ce moment la, fais en une fonction libre, friend.


 
L'operateur << par exemple ?
 
Je ne comprends pas, pour faire la surcharge de cet operateur il suffit de déclarer une fonction exterieure, de delui fournir la classe en paramètres et de créer des accesseurs, non ?
Qu'es ce que "friend" vient faire la dedans ?

Reply

Marsh Posté le 02-10-2005 à 22:43:54    

Citation :

L'operateur << par exemple ?


 
Oui.
 

Citation :

Je ne comprends pas, pour faire la surcharge de cet operateur il suffit de déclarer une fonction exterieure, de delui fournir la classe en paramètres et de créer des accesseurs, non ?


 
ça t'oblige à créer des accesseurs, et une fonction fantome, qui jouera le même rôle que l'operateur, et qui sera publique si elle est membre.
 

Citation :

Qu'es ce que "friend" vient faire la dedans ?


 
tu ne vois vraiment pas ?

Reply

Marsh Posté le 02-10-2005 à 22:43:54   

Reply

Marsh Posté le 02-10-2005 à 23:41:30    

++fab a écrit :


Citation :

Je ne comprends pas, pour faire la surcharge de cet operateur il suffit de déclarer une fonction exterieure, de delui fournir la classe en paramètres et de créer des accesseurs, non ?


 
ça t'oblige à créer des accesseurs, et une fonction fantome, qui jouera le même rôle que l'operateur, et qui sera publique si elle est membre.
 

Citation :

Qu'es ce que "friend" vient faire la dedans ?


 
tu ne vois vraiment pas ?


 
Si on adopte la première solution, la seconde devient inutile.
Et la première n'est pas meilleure ? (moi c'est ce qu'on m'a appris)

Reply

Marsh Posté le 02-10-2005 à 23:49:19    

mcyrb a écrit :

Si on adopte la première solution, la seconde devient inutile.
Et la première n'est pas meilleure ? (moi c'est ce qu'on m'a appris)


 
Rien compris, quelles sont les deux solutions dont tu parles ?

Reply

Marsh Posté le 03-10-2005 à 01:12:54    

En fait, je parlais de surcharge de l'operateur << dans le but de l'utiliser pour afficher le contenu des attributs d'une classe (c'est la seule que j'ai eu l'occasion d'utiliser), donc dans ce cas, soit on utilise des accesseurs, soit une fonction amie (on m'a vivement recommandé les accesseurs).
Donc j'aurais voulu savoir si dans certains cas l'utilisation de fonction amie était préférable... etant donné que t'as l'air de dire que c'est bien alors qu'on m'a toujours dit d'eviter au maximum (je parle de cas ou l'utilsation de fonction amie n'est pas la seule solution).

Message cité 1 fois
Message édité par mcyrb le 03-10-2005 à 01:17:50
Reply

Marsh Posté le 03-10-2005 à 07:37:14    

mcyrb a écrit :

En fait, je parlais de surcharge de l'operateur << dans le but de l'utiliser pour afficher le contenu des attributs d'une classe (c'est la seule que j'ai eu l'occasion d'utiliser), donc dans ce cas, soit on utilise des accesseurs, soit une fonction amie (on m'a vivement recommandé les accesseurs).


 
et on a bien fait. Si tu as des accesseurs, tu t'en sers. Tu les met inline si c'est pénalisant en performance, ou si tu l'anticipes. Et tu évites le friend.  
Mais il y a des cas ou tu n'a pas (envi/usage de fournir des) d'accesseurs, alors friend est la pour ça.
 

Citation :

Donc j'aurais voulu savoir si dans certains cas l'utilisation de fonction amie était préférable... etant donné que t'as l'air de dire que c'est bien alors qu'on m'a toujours dit d'eviter au maximum (je parle de cas ou l'utilsation de fonction amie n'est pas la seule solution)

.
 
*dans certains cas*, l'utilisation d'une fonction friend inline est avantageuse. Pour une classe ayant un constructeur délibérement non explicit (à voir en seconde lecture).

Reply

Marsh Posté le 03-10-2005 à 09:07:41    

++fab a écrit :

Si ta fonction n'a pas besoin d'avoir l'acces aux membres privés ou protégés de ta classe, fais en une fonction libre, non friend. (pas le cas le plus courant)
Dans le cas contraire, fais en une fonction membre.
Et enfin, certaines surcharges d'operateurs ne peuvent pas etre défini en tant que membre, mais ont besoin des membres protégés ou privés de ta classe. A ce moment la, fais en une fonction libre, friend.


 
 
quelles sont les surcharges d'operateur qui ne peuvent etre defini en tant que membre et pourquoi?

Reply

Marsh Posté le 04-10-2005 à 20:48:22    

les operateurs << et >>. Ce sont les seuls en fait. Il y en a d'autre pour lesquels il n'est pas judicieux d'en faire des fonctions membres. C'est à voir quasiment au cas par cas. Et c'est presque à retenir par coeur parce que c'est assez piegeux :(
 
pourquoi << et >> ?
struct Foo {};
Foo foo;
tu écris cout << foo;
C'est interprété soit en (1) operator<<(std::ostream, foo), soit en (2) std::ostream::operator<<( foo )
 
(2) n'existe pas dans basic_ostream<>. Donc il faut utiliser (1)
Idem pour >>.


Message édité par ++fab le 04-10-2005 à 21:03:23
Reply

Marsh Posté le 04-10-2005 à 21:47:29    

++fab a écrit :


 

Citation :

- quand déclare-t-on une fonction amie a une classe? j'ai bien compris que cela servait a ce que la fonction ait accès aux parties privées de la classe mais je doute quon le fasse systématiquement (sinon a quoi bon déclarer des méthodes ou des attributs en private)


 
pour surcharger des operateurs non membre, comme l'inserteur ou l'extracteur (<<, >>, ...), ça a un sens.
Meme si d'autre te dirons peut etre, c'est la mal, t'as qu'a faire une fonction membre publique print() et l'operateur (inline) appelle print(). Je trouve ça inélégant au possible.


 
par contre, pour emuler un operator<< virtuel, j'aime bien faire ça :
 

Code :
  1. class B
  2. {
  3. public:
  4.       virtual ~B() {}
  5. private:
  6.     virtual void print() const = 0;
  7.    
  8.     friend inline std::ostream& operator<<( std::ostream& os, B const & b )
  9. {
  10.     b.print();
  11. }
  12. };
  13. class D : public B
  14. {
  15. private:
  16.     virtual void print() const { std::cout << "heho\n"; }
  17. };
  18. int main()
  19. {
  20.     B* d = new D();
  21.     std::cout << *d;
  22.     delete d;
  23. }

Reply

Marsh Posté le 05-10-2005 à 11:25:39    

c'est balot de prendre une reference sur un ostream pour ensuite aller ecrire sur std::cout sans rien demander a personne [:god]

Reply

Marsh Posté le 05-10-2005 à 11:35:42    

ouais bon,  :sleep:  
 
    * class B
    * {
    * public:
    *       virtual ~B() {}
    * private:
    *     virtual void print( std::ostream& os ) const = 0;
    *      
    *     friend inline std::ostream& operator<<( std::ostream& os, B const & b )
    *     {
    *         b.print( os );
    *     }
    * };
    *
    * class D : public B
    * {
    * private:
    *     virtual void print( std::ostream& os ) const { os << "hehon"; }
    * };
    *
    * int main()
    * {
    *     B* d = new D();
    *     std::cout << *d;
    *     delete d;
    * }

Reply

Marsh Posté le 05-10-2005 à 11:38:37    

Faut être précis, on est sur un topic débutant mon cher, pédagogie et clarté [:dawao]

Reply

Marsh Posté le 05-10-2005 à 19:01:04    

Ah ? Je croyais que pour un topic débutant c'était plutot :o et RTFM nOOb. Au temps pour moi.

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed