getters et setters : style ?

getters et setters : style ? - C++ - Programmation

Marsh Posté le 11-01-2005 à 11:15:40    

Bonjour,
 
Je suis en auto-formation sur C++ avec le livre de Bjarne Stroustrup. J'ai créé hier ma première classe, et je me pose une question sur les setters et les getters.
 

Code :
  1. class Person
  2. {
  3.   private:
  4.     int age;
  5.     string name;
  6.   public:
  7.     int get_age();
  8.     void set_age(int age);
  9.     string get_name();
  10.     void set_name(string name);
  11. }


 
Plus je regarde le code, et plus je me demande si mes getters et setters ne devraient pas travailler avec des références ou des pointeurs. Mon peu de culture m'empêche de trancher.
 
Vous feriez quoi, vous ?


---------------
La différence entre la théorie et la pratique c'est qu'en théorie il n'y a pas de différence, mais qu'en pratique il y en a une.
Reply

Marsh Posté le 11-01-2005 à 11:15:40   

Reply

Marsh Posté le 11-01-2005 à 11:25:55    

euh je vois pas bien l'intérêt...
 
par contre je te conseille de les déclarer inline
 
exemple
 
int get_age() {return age};
void set_age(int a) {age = a;}

Reply

Marsh Posté le 11-01-2005 à 11:32:42    

Peut-être passer la string par réfèrence constante ?

Reply

Marsh Posté le 11-01-2005 à 11:38:59    

et les const ??? (pour les get*)

Reply

Marsh Posté le 11-01-2005 à 12:00:53    

spokup a écrit :

euh je vois pas bien l'intérêt...
 
par contre je te conseille de les déclarer inline
 
exemple
 
int get_age() {return age};
void set_age(int a) {age = a;}


J'ai pas encore vu l'inlining.  :o  
 

++fab a écrit :

et les const ??? (pour les get*)


Il faut déclarer les getters const ? Qu'est-ce que ça va changer ?
 
 

cricri_ a écrit :

Peut-être passer la string par réfèrence constante ?


Je me damnde en effet, si :

Code :
  1. public:
  2.     void set_name(string& name);


n'est pas plus adapté. Mais là encore l'apport de const me trouble. Je ne viens pas vraiment ce que cela apporte.


Message édité par Mutsumi le 11-01-2005 à 14:34:31

---------------
La différence entre la théorie et la pratique c'est qu'en théorie il n'y a pas de différence, mais qu'en pratique il y en a une.
Reply

Marsh Posté le 11-01-2005 à 12:07:32    

Mutsumi a écrit :


Il faut déclarer les getters const ? Qu'est-ce que ça va changer ?


 
moulte
si plus tard tu recuperes 'const Person [&/*/...]' ca te permettra d'appeler le geter (vu qu'il est aussi declaré const. Sur un object 'const' ne peux appeler que des fonctions 'const')
 
D'une certaine maniere c'est une bonne habitude a prendre de mettre des 'const' la ou y'en faut (sur les constantes (virage des vieux #define par ex), sur sur les fonctions ne faisant rien, et la, typiquement ton  

Code :
  1. std::string getName()


 
serait tout aussi bien en  
 

Code :
  1. const std::string & getName() const;


 
(on retourne une reference (plus leger a retourner qu'un nouvel objet), mais on interdit la modification du contenu de cette reference. Par ailleurs vu que notre fonction ne touche pas en ecriture a ses données membre on la déclare const)


Message édité par chrisbk le 11-01-2005 à 12:08:31
Reply

Marsh Posté le 11-01-2005 à 14:05:31    

chrisbk a écrit :


Code :
  1. const std::string & getName() const;




Si je reformule afin de vérifier que j'ai compris, alors on déclare une méthode const, ie qui garantie qu'on ne modifie pas l'état de l'instance, et en plus on déclare que la référence retournée est const, ie que l'on ne peut pas la modifier. Quel genre de modifications sur la référence sont interdites (je ne suis pas sûr que ma question ait un sens) ?


---------------
La différence entre la théorie et la pratique c'est qu'en théorie il n'y a pas de différence, mais qu'en pratique il y en a une.
Reply

Marsh Posté le 11-01-2005 à 14:27:19    

Mutsumi a écrit :

Si je reformule afin de vérifier que j'ai compris, alors on déclare une méthode const, ie qui garantie qu'on ne modifie pas l'état de l'instance, et en plus on déclare que la référence retournée est const, ie que l'on ne peut pas la modifier. Quel genre de modifications sur la référence sont interdites (je ne suis pas sûr que ma question ait un sens) ?


 
bin tout ce qui sera 'non const' sur la reference, genre '=', les fonctions 'non-const', l'acces en ecriture a des variables publics...

Reply

Marsh Posté le 11-01-2005 à 14:33:53    

chrisbk a écrit :

bin tout ce qui sera 'non const' sur la reference, genre '=', les fonctions 'non-const', l'acces en ecriture a des variables publics...


J'ai compris quelque chose moi.
 

Code :
  1. void set_name(std::string & name);


 
Est-ce que la référence est const ici ? Pour moi oui. J'écrirais volontiers :

Code :
  1. void set_name(const std::string & name);


 
Et pour des bêtes int, on préfère la copie ou la référence ?


---------------
La différence entre la théorie et la pratique c'est qu'en théorie il n'y a pas de différence, mais qu'en pratique il y en a une.
Reply

Marsh Posté le 11-01-2005 à 14:41:28    

Mutsumi a écrit :

J'ai compris quelque chose moi.
 

Code :
  1. void set_name(std::string & name);


 
Est-ce que la référence est const ici ? Pour moi oui. J'écrirais volontiers :

Code :
  1. void set_name(const std::string & name);




et tu fais fais bien
 

Mutsumi a écrit :


Et pour des bêtes int, on préfère la copie ou la référence ?


 
bin pour le int (et les autres types primitifs tels que float, double, char...), tu suis generalement le schema suivant :
parametre de type in : copie
parametre de type in/out, out : reference
 
 
 
 

Reply

Marsh Posté le 11-01-2005 à 14:41:28   

Reply

Marsh Posté le 11-01-2005 à 14:54:11    

Bon, ben c'est super. Je pense que j'ai compris. Merci beaucoup à tous.


---------------
La différence entre la théorie et la pratique c'est qu'en théorie il n'y a pas de différence, mais qu'en pratique il y en a une.
Reply

Marsh Posté le 11-01-2005 à 15:02:13    

un autre schéma :
tu es sur que la taille de l'objet à passer est inférieur ou égal à la taille d'un pointeur (ou tu le suppose fortement) (*) --> copie
dans le cas contraire --> reférence ou référence constante.
Si tu ne peux pas savoir (taille non borné, généricité, ...)
--> référence ou référence constante.
EDIT: NB : pour les types de retour, il faut etre conscient du risque pris en retournant une référence. Ainsi que des limitations qu'engendrent le retour d'une référence constante.
 
(*) La norme ne dit rien sur la taille d'un type intégré ...
Elle établit juste une relation < entre certains. La taille d'un pointeur est elle aussi variable suivant les architectures.


Message édité par ++fab le 11-01-2005 à 17:33:01
Reply

Marsh Posté le 11-01-2005 à 17:11:56    

:jap:


---------------
La différence entre la théorie et la pratique c'est qu'en théorie il n'y a pas de différence, mais qu'en pratique il y en a une.
Reply

Marsh Posté le 11-01-2005 à 17:23:10    

j'aimerais bien que certaines réléchissent un peu avant de coller des références partout. Même si tout à déjà était dit, faut vous mettre profond que
 
& -> modification
const & -> lecture seule
this -> modification
const this -> lecture seule.
 
la question n'est pas "qu'est-ce qui est rapide" mais "qu'est-ce qui est correcte". Ton getter pas const, c'est pas un accesseur, c'est un modificateur. Ton setter avec paramètre par référence, il est gentil mais il risque de défoncer son paramètre.
 
parametre de type in : copie
gros paramètre de type in : const reference
parametre de type in/out, out : reference
 
 
les même règles s'appliquent à this, paramètre implicite des fonctions membres

Reply

Marsh Posté le 12-01-2005 à 23:07:03    

je comprends pas bien ton const this
tu veux dire qu'on peut ecrire dans du code 'const this' ?
et que du coup ca donne un pointeur de type 'MaClass const * const' au lieu de 'MaClass * const' pour this dans une methode pas const ?
 
si c'est ça je connaissais pas, et je vois pas trop l'interet, vu qu'un truc pas const se tranforme tout seul en const si jamais il est utilisé par quelquechose qui veut du const.

Reply

Marsh Posté le 13-01-2005 à 00:04:47    

Taz a écrit :


parametre de type in : copie
gros paramètre de type in : const reference
parametre de type in/out, out : reference


 
const ne passe pas que l'adresse ?
(bête question, mais comme en Delphi c'est le cas je pensais qu'en C++ ça l'était aussi - const seul n'a pas d'effet au niveau du code généré alors ?)


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 13-01-2005 à 00:20:55    

me semble que const n'a jamais d'effet sur le code généré, c'est surtout un garde-fou pour l'utilisation de la classe.
 
Oualb : l'interet =>
 
void foo(const Bar &b);
 
=> dans foo, tu ne pourras utiliser que les méthodes const de b.


---------------
-( BlackGoddess )-
Reply

Marsh Posté le 13-01-2005 à 01:10:38    

Bien sur que const a un effet sur le code généré !

Reply

Marsh Posté le 13-01-2005 à 12:14:08    

Reply

Marsh Posté le 13-01-2005 à 12:27:30    

pourquoi tout le monde veut absolument un set et un get, alors que la meme fonction du nom du membre peut être surchargé.
 
Et puis y a des couches template qui existent pour faire ça comme des property C# / Python

Reply

Marsh Posté le 13-01-2005 à 13:01:55    

boost::call_traits est très pratique quand on ne sait pas quel est le meilleur choix pour passer un paramètre à une fonction ou renvoyer une valeur d'une fonction (notamment quand on ne connait pas le type du paramètre). Au pire, on peut s'inspirer du tableau dans la doc pour choisir...


---------------
each day I don't die is cheating
Reply

Marsh Posté le 13-01-2005 à 13:06:25    

Reply

Marsh Posté le 13-01-2005 à 14:03:34    

Un thread intéressant aussi:
http://www.google.fr/groups?hl=fr& [...] %26hl%3Dfr


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 13-01-2005 à 19:47:50    

blackgoddess a écrit :

me semble que const n'a jamais d'effet sur le code généré, c'est surtout un garde-fou pour l'utilisation de la classe.
 
Oualb : l'interet =>
 
void foo(const Bar &b);
 
=> dans foo, tu ne pourras utiliser que les méthodes const de b.


 
t'es gentil merci ca je sais  
relis ma question et tu verras qu'elle porte sur l'expression 'const this' et pas sur 'const ' en soi même
 
d'ailleurs ca serait bien que Taz me réponde si ca le dérangeait pas trop

Reply

Marsh Posté le 13-01-2005 à 19:58:43    

bin rien, ton 'this' se transforme en 'const this' dans une fonction 'const', c'est tout (si je comprends bien ta question)

Reply

Marsh Posté le 13-01-2005 à 19:59:51    

Oualb a écrit :

je comprends pas bien ton const this
tu veux dire qu'on peut ecrire dans du code 'const this' ?


 
void A::f() const;

Oualb a écrit :


 
 
et que du coup ca donne un pointeur de type 'MaClass const * const' au lieu de 'MaClass * const' pour this dans une methode pas const ?

commence par plcer les const comme il faut.
 
'const MaClasse * const'.
 
j'espère que tu t'es déjà aperçu que
 
this = x;
 
est une erreur;
 

Oualb a écrit :


si c'est ça je connaissais pas, et je vois pas trop l'interet, vu qu'un truc pas const se tranforme tout seul en const si jamais il est utilisé par quelquechose qui veut du const.

je vois pas le rapport.

Reply

Marsh Posté le 13-01-2005 à 20:17:08    

Reply

Marsh Posté le 13-01-2005 à 20:22:13    

blackgoddess a écrit :

me semble que const n'a jamais d'effet sur le code généré, c'est surtout un garde-fou pour l'utilisation de la classe.
 
Oualb : l'interet =>
 
void foo(const Bar &b);
 
=> dans foo, tu ne pourras utiliser que les méthodes const de b.


Ben si, A::foo(const Bar &x) et A::foo(Bar &x) sont bien deux méthodes différentes de A. Ca va au-dela du simple garde-fou du compilo. Evidemment, si tu as besoin une fois ou deux de A::foo(Bar &x) alors que seul A::foo(const Bar &x) est définie, il ne faut pas définir A::foo(Bar &x) parce qu'alors, la version const ne sert plus à rien (vu que le constness peut être court-circuité), il faut const_cast-er.
 
edit : mon exemple était con [:itm]


Message édité par el muchacho le 13-01-2005 à 20:26:15
Reply

Marsh Posté le 13-01-2005 à 22:54:40    

non mais c'est quand meme incroyable ca !!!!!!!!!!
 
vous comprenez le francais ou quoi ????????
je demande pas qu'on m'explique ce que veut dire const merde
 
je demande juste si ecrire

Code :
  1. const this

 ca a un sens ou pas, en rapport avec ce que disait Taz dans son post un peut avant

Reply

Marsh Posté le 13-01-2005 à 22:57:00    

chrisbk a écrit :

bin rien, ton 'this' se transforme en 'const this' dans une fonction 'const', c'est tout (si je comprends bien ta question)


 
enfin un qui comprend
oui c'est un peu ca mais on l'appelle toujours 'this' dans le code, pas 'const this'
certes il n'est pas du même type, mais c'est quand meme le même mot

Reply

Marsh Posté le 13-01-2005 à 22:59:24    

Oualb a écrit :

enfin un qui comprend
oui c'est un peu ca mais on l'appelle toujours 'this' dans le code, pas 'const this'
certes il n'est pas du même type, mais c'est quand meme le même mot


 
 
non, bin oui, parce que "const this" c'est foireux comme expression
Imaginons une classe A
 
dans une fonction membre non const, this sera de type 'A*'
dans une fonction membre const, this sera de type 'const A*'
 
y'a pas vraiment de const this, quoi. Mais on se comprends quand on parle de 'const this' [:icon7]


Message édité par chrisbk le 13-01-2005 à 22:59:56
Reply

Marsh Posté le 13-01-2005 à 23:08:55    

voila

Reply

Marsh Posté le 13-01-2005 à 23:21:19    

Oualb a écrit :

non mais c'est quand meme incroyable ca !!!!!!!!!!
 
vous comprenez le francais ou quoi ????????
je demande pas qu'on m'explique ce que veut dire const merde
 
je demande juste si ecrire

Code :
  1. const this

 ca a un sens ou pas, en rapport avec ce que disait Taz dans son post un peut avant


Non mais c'est pas  à toi que je répondais ! :kaola:  
Pis const merde, je connais pas.  :whistle:

Reply

Marsh Posté le 15-01-2005 à 12:00:45    

Par rapport au lien donné par Taz, je ne comprends pas pourquoi le code suivant fonctionne :
 
dans la classe de test, on a :

Code :
  1. ROProperty< int, myClass, &myClass::myKids > NumberOfChildren;


et dans le constructeur :

Code :
  1. NumberOfChildren(this);


pour que ROProperty puisse appeller la fonction myKids :

Code :
  1. Object *my_object;
  2. public:
  3.     void operator () (Object * obj)
  4.     {
  5.         my_object = obj;
  6.     }


Bon jusque là pas de pb, mais lorsque je mets en commentaire NumberOfChildren(this); ca fonctionne.
Donc je vois pas comment sans initialiser my_object, ca peut marcher.

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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